%   File   : sudoku.pl (in B-Prolog)
%   Author : Neng-Fa ZHOU
%   Date   : 1996 & GUI added in 2001
%   Purpose: solve a Japanese arithmetic puzzle (9*9), added graphics in 2001

go:-
    cgWindow(Win,"Sudoku"),
    handleWindowClosing(Win),
    Win^topMargin #= 30, Win^leftMargin #= 10,
    cgLabel(Lab,"Problems"),Lab^window #= Win,
    cgChoice(Choice), Choice^window #= Win, Choice^width #> 100,
    cgAdd(Choice,["Sudoku250","Sudoku81","Sudoku368","Sudoku378"]),
    Board=board([]),
    handleChoice(Lab,Choice,Board,Win),
    cgTable([[Lab,Choice]]),
    cgStartRecord(sudoku),
    cgShow([Lab,Choice]),
    call_sudoku("Sudoku250",Lab,Choice,Board,Win).

handleWindowClosing(Win),{windowClosing(Win)} => cgClose(Win).

call_sudoku(Prob,Lab,Choice,Board,Win):-
    sudoku(Prob,Os),
    setarg(1,Board,Os),
    cgAbove([Lab,Choice],Os),
    cgSame(Os,window,Win),
    cgShow(Os),
    cgStopRecord.

handleChoice(Lab,Choice,Board,Win),{itemStateChanged(Choice,E)} =>
    cgSelectedItem(Choice,Prob),
    Board=board(Os),
    cgClean(Os), %remove the buttons
    call_sudoku(Prob,Lab,Choice,Board,Win).

sudoku("Sudoku81",Os):-
    new_array(AVars,[9,9]),
    AVars @= [[A11,A12,A13,B11,B12,B13,C11,C12,C13],
	     [A21,A22,A23,B21,B22,B23,C21,C22,C23],
	     [A31,A32,A33,B31,B32,B33,C31,C32,C33],
	     [D11,D12,D13,E11,E12,E13,F11,F12,F13],
	     [D21,D22,D23,E21,E22,E23,F21,F22,F23],
	     [D31,D32,D33,E31,E32,E33,F31,F32,F33],
	     [G11,G12,G13,H11,H12,H13,I11,I12,I13],
	     [G21,G22,G23,H21,H22,H23,I21,I22,I23],
	     [G31,G32,G33,H31,H32,H33,I31,I32,I33]],
    array_to_list(AVars,Vars),
    Vars in 1..9,
    A12=6,B11=2,B13=4,C12=5,
    A21=4,A22=7,B22=6,C22=8,C23=3,
    A33=5,
    B32=7,
    C31=1,
    D11=9,E11=1,E13=3,F13=2,
    D22=1,D23=2,F23=9,
    D31=6,E31=7,E33=9,F33=8,
    G13=6,H12=8,I11=7,
    G21=1,G22=4,H22=9,I22=2,I23=5,
    G32=8,H31=3,H33=5,I32=9,
    %
    sudoku_alldistinct(AVars),
    labeling_ff(Vars),
    visualizeSudoku(AVars,Os).

sudoku("Sudoku250",Os):-
    new_array(AVars,[25,25]),
    AVars @= [[A11,A12,A13,A14,A15,B11,B12,B13,B14,B15,C11,C12,C13,C14,C15,D11,D12,D13,D14,D15,E11,E12,E13,E14,E15],
	      [A21,A22,A23,A24,A25,B21,B22,B23,B24,B25,C21,C22,C23,C24,C25,D21,D22,D23,D24,D25,E21,E22,E23,E24,E25],
	      [A31,A32,A33,A34,A35,B31,B32,B33,B34,B35,C31,C32,C33,C34,C35,D31,D32,D33,D34,D35,E31,E32,E33,E34,E35],
	      [A41,A42,A43,A44,A45,B41,B42,B43,B44,B45,C41,C42,C43,C44,C45,D41,D42,D43,D44,D45,E41,E42,E43,E44,E45],
	      [A51,A52,A53,A54,A55,B51,B52,B53,B54,B55,C51,C52,C53,C54,C55,D51,D52,D53,D54,D55,E51,E52,E53,E54,E55],
	      [F11,F12,F13,F14,F15,G11,G12,G13,G14,G15,H11,H12,H13,H14,H15,I11,I12,I13,I14,I15,J11,J12,J13,J14,J15],
	      [F21,F22,F23,F24,F25,G21,G22,G23,G24,G25,H21,H22,H23,H24,H25,I21,I22,I23,I24,I25,J21,J22,J23,J24,J25],
	      [F31,F32,F33,F34,F35,G31,G32,G33,G34,G35,H31,H32,H33,H34,H35,I31,I32,I33,I34,I35,J31,J32,J33,J34,J35],
	      [F41,F42,F43,F44,F45,G41,G42,G43,G44,G45,H41,H42,H43,H44,H45,I41,I42,I43,I44,I45,J41,J42,J43,J44,J45],
	      [F51,F52,F53,F54,F55,G51,G52,G53,G54,G55,H51,H52,H53,H54,H55,I51,I52,I53,I54,I55,J51,J52,J53,J54,J55],
	      [K11,K12,K13,K14,K15,L11,L12,L13,L14,L15,M11,M12,M13,M14,M15,N11,N12,N13,N14,N15,O11,O12,O13,O14,O15],
	      [K21,K22,K23,K24,K25,L21,L22,L23,L24,L25,M21,M22,M23,M24,M25,N21,N22,N23,N24,N25,O21,O22,O23,O24,O25],
	      [K31,K32,K33,K34,K35,L31,L32,L33,L34,L35,M31,M32,M33,M34,M35,N31,N32,N33,N34,N35,O31,O32,O33,O34,O35],
	      [K41,K42,K43,K44,K45,L41,L42,L43,L44,L45,M41,M42,M43,M44,M45,N41,N42,N43,N44,N45,O41,O42,O43,O44,O45],
	      [K51,K52,K53,K54,K55,L51,L52,L53,L54,L55,M51,M52,M53,M54,M55,N51,N52,N53,N54,N55,O51,O52,O53,O54,O55],
	      [P11,P12,P13,P14,P15,Q11,Q12,Q13,Q14,Q15,R11,R12,R13,R14,R15,S11,S12,S13,S14,S15,T11,T12,T13,T14,T15],
	      [P21,P22,P23,P24,P25,Q21,Q22,Q23,Q24,Q25,R21,R22,R23,R24,R25,S21,S22,S23,S24,S25,T21,T22,T23,T24,T25],
	      [P31,P32,P33,P34,P35,Q31,Q32,Q33,Q34,Q35,R31,R32,R33,R34,R35,S31,S32,S33,S34,S35,T31,T32,T33,T34,T35],
	      [P41,P42,P43,P44,P45,Q41,Q42,Q43,Q44,Q45,R41,R42,R43,R44,R45,S41,S42,S43,S44,S45,T41,T42,T43,T44,T45],
	      [P51,P52,P53,P54,P55,Q51,Q52,Q53,Q54,Q55,R51,R52,R53,R54,R55,S51,S52,S53,S54,S55,T51,T52,T53,T54,T55],
	      [U11,U12,U13,U14,U15,V11,V12,V13,V14,V15,W11,W12,W13,W14,W15,X11,X12,X13,X14,X15,Y11,Y12,Y13,Y14,Y15],
	      [U21,U22,U23,U24,U25,V21,V22,V23,V24,V25,W21,W22,W23,W24,W25,X21,X22,X23,X24,X25,Y21,Y22,Y23,Y24,Y25],
	      [U31,U32,U33,U34,U35,V31,V32,V33,V34,V35,W31,W32,W33,W34,W35,X31,X32,X33,X34,X35,Y31,Y32,Y33,Y34,Y35],
	      [U41,U42,U43,U44,U45,V41,V42,V43,V44,V45,W41,W42,W43,W44,W45,X41,X42,X43,X44,X45,Y41,Y42,Y43,Y44,Y45],
	      [U51,U52,U53,U54,U55,V51,V52,V53,V54,V55,W51,W52,W53,W54,W55,X51,X52,X53,X54,X55,Y51,Y52,Y53,Y54,Y55]],
    array_to_list(AVars,Vars),
    Vars in 1..25,
    A11#=8, A22#=18, A23#=24, A24#=22, A32#=21, A33#=23, A34#=13, 
    A42#=15, A43#=1, A44#=20, A55#=17,
    B11#=21, B12#=15, B14#=6, B21#=19, B23#=4, B32#=10, B35#=1, 
    B41#=18, B45#=13, B53#=24, B54#=11, B55#=12, 
    C11#=19, C13#=1, C15#=11, C21#=7, C23#=2, C25#=8, C32#=14, 
    C33#=3, C34#=22, C42#=24, C43#=4, C44#=16, C53#=5,
    D12#=4, D14#=14, D15#=3, D23#=1, D25#=12, D31#=5, D34#=11, 
    D41#=19, D45#=2, D51#=15, D52#=13, D53#=18,
    E15#=22, E22#=21, E23#=14, E24#=9, E32#=20, E33#=12, E34#=25, 
    E42#=7, E43#=23, E44#=17, E51#=16,
    F11#=13, F12#=17, F14#=3, F21#=2, F23#=5, F32#=6, F35#=16, 
    F41#=21, F44#=4, F45#=10, F53#=18, F54#=1, F55#=20,
    G12#=19, G13#=20, G14#=5, G21#=25, G22#=6, G31#=13, G34#=3, 
    G35#=9, G41#=8, G43#=15, G53#=7,
    H13#=6, H22#=19, H23#=7, H24#=21, H32#=1, H33#=8, H34#=4, 
    H41#=12, H43#=9, H45#=23, H51#=3, H53#=10, H55#=25,
    I12#=23, I13#=16, I14#=24, I24#=3, I25#=11, I31#=2, I32#=10, 
    I35#=7, I43#=6, I45#=14, I53#=15,
    J12#=25, J14#=12, J15#=14, J23#=17, J25#=20, J31#=24, J34#=15, 
    J41#=11, J42#=3, J45#=7, J51#=4, J52#=13, J53#=6,
    K11#=14, K12#=4, K23#=13, K24#=8, K31#=11, K33#=6, K34#=12, 
    K35#=7, K43#=3, K44#=9, K51#=22, K52#=25, 
    L14#=8, L15#=20, L22#=22, L23#=14, L31#=3, L35#=17, L42#=12, 
    L43#=6, L54#=7, L55#=4,
    M12#=3, M13#=11, M14#=19, M21#=24, M22#=20, M24#=18, M25#=17, 
    M31#=23, M33#=13, M35#=4, M41#=5, M42#=22, M44#=10, M45#=21, 
    M52#=16, M53#=15, M54#=9,
    N11#=1, N12#=12, N23#=11, N24#=7, N31#=8, N35#=15, N43#=13, 
    N44#=18, N51#=17, N52#=3,
    O14#=18, O15#=23, O22#=19, O23#=9, O31#=20, O32#=14, O33#=16, 
    O35#=21, O42#=8, O43#=15, O54#=5, O55#=13,
    P13#=21, P14#=17, P15#=6, P21#=23, P24#=24, P25#=15, P32#=16, 
    P35#=25, P41#=1, P43#=9, P51#=12, P52#=2, P54#=11,
    Q13#=8, Q21#=7, Q23#=11, Q31#=10, Q34#=23, Q35#=24, Q41#=6, 
    Q42#=14, Q52#=25, Q53#=21, Q54#=4,
    R11#=15, R13#=16, R15#=5, R21#=2, R23#=17, R25#=14, R32#=13, 
    R33#=18, R34#=12, R42#=10, R43#=19, R44#=7, R53#=20,
    S13#=2, S23#=10, S25#=21, S31#=3, S32#=20, S35#=9, S44#=12, 
    S45#=8, S52#=14, S53#=22, S54#=1,
    T11#=13, T12#=1, T13#=20, T21#=25, T22#=9, T25#=16, T31#=14, 
    T34#=11, T43#=2, T45#=15, T52#=18, T54#=23, T55#=5,
    U15#=5, U22#=12, U23#=14, U24#=6, U32#=1, U33#=11, U34#=7, 
    U42#=10, U43#=22, U44#=19, U51#=15,
    V13#=13, V14#=19, V15#=14, V21#=15, V25#=8, V32#=4, V35#=22, 
    V41#=5, V43#=18, V51#=23, V52#=7, V54#=17,
    W13#=21, W22#=17, W23#=22, W24#=20, W32#=6, W33#=23, W34#=5, 
    W41#=16, W43#=24, W45#=15, W51#=11, W53#=25, W55#=18,
    X11#=23, X12#=6, X13#=12, X21#=16, X25#=24, X31#=18, X34#=17, 
    X43#=21, X45#=25, X52#=19, X54#=13, X55#=1,
    Y11#=1, Y22#=5, Y23#=13, Y24#=10, Y32#=12, Y33#=21, Y34#=2, 
    Y42#=11, Y43#=7, Y44#=14, Y55#=6,
    E14#=13, 
    D21#=10,
    E21#=6, E25#=3,
    C45#=12, D42#=21,
    C52#=21, 
    E54#=19, E55#=1,
    H12#=11, H14#=15,
    J11#=10, J13#=1, 
    H21#=13, H25#=16,
    I33#=25, 
    H44#=24, I41#=13, 
    I55#=17, J55#=2,
    M11#=6, M15#=7, 
    O11#=2, O12#=17,
    M23#=12, N21#=21, 
    O24#=6, O25#=10,
    N33#=19, 
    M43#=14, N41#=20, 
    M51#=8, M55#=1, 
    O52#=24, O53#=11, 
    R12#=23, R14#=11,
    T14#=7, 
    R24#=1, S21#=6, 
    S33#=17, S34#=15,
    T33#=8, T35#=19,
    R41#=25, R45#=3,
    T42#=4, T44#=24,
    R54#=6, R55#=24, 
    T51#=17, T53#=10, 
    W11#=4, W12#=7, 
    Y14#=3, Y15#=9,
    W25#=19, X22#=11, 
    X32#=15, 
    X35#=10, Y31#=19, Y35#=8,
    W44#=3, X41#=4, X42#=9,
    W52#=9, W54#=8, 
    %
    sudoku_alldistinct(AVars),
    labeling_ff(Vars),
    visualizeSudoku(AVars,Os).

sudoku("Sudoku368",Os):-
    new_array(AVars,[25,25]),
    AVars @= [[A11,A12,A13,A14,A15,B11,B12,B13,B14,B15,C11,C12,C13,C14,C15,D11,D12,D13,D14,D15,E11,E12,E13,E14,E15],
	      [A21,A22,A23,A24,A25,B21,B22,B23,B24,B25,C21,C22,C23,C24,C25,D21,D22,D23,D24,D25,E21,E22,E23,E24,E25],
	      [A31,A32,A33,A34,A35,B31,B32,B33,B34,B35,C31,C32,C33,C34,C35,D31,D32,D33,D34,D35,E31,E32,E33,E34,E35],
	      [A41,A42,A43,A44,A45,B41,B42,B43,B44,B45,C41,C42,C43,C44,C45,D41,D42,D43,D44,D45,E41,E42,E43,E44,E45],
	      [A51,A52,A53,A54,A55,B51,B52,B53,B54,B55,C51,C52,C53,C54,C55,D51,D52,D53,D54,D55,E51,E52,E53,E54,E55],
	      [F11,F12,F13,F14,F15,G11,G12,G13,G14,G15,H11,H12,H13,H14,H15,I11,I12,I13,I14,I15,J11,J12,J13,J14,J15],
	      [F21,F22,F23,F24,F25,G21,G22,G23,G24,G25,H21,H22,H23,H24,H25,I21,I22,I23,I24,I25,J21,J22,J23,J24,J25],
	      [F31,F32,F33,F34,F35,G31,G32,G33,G34,G35,H31,H32,H33,H34,H35,I31,I32,I33,I34,I35,J31,J32,J33,J34,J35],
	      [F41,F42,F43,F44,F45,G41,G42,G43,G44,G45,H41,H42,H43,H44,H45,I41,I42,I43,I44,I45,J41,J42,J43,J44,J45],
	      [F51,F52,F53,F54,F55,G51,G52,G53,G54,G55,H51,H52,H53,H54,H55,I51,I52,I53,I54,I55,J51,J52,J53,J54,J55],
	      [K11,K12,K13,K14,K15,L11,L12,L13,L14,L15,M11,M12,M13,M14,M15,N11,N12,N13,N14,N15,O11,O12,O13,O14,O15],
	      [K21,K22,K23,K24,K25,L21,L22,L23,L24,L25,M21,M22,M23,M24,M25,N21,N22,N23,N24,N25,O21,O22,O23,O24,O25],
	      [K31,K32,K33,K34,K35,L31,L32,L33,L34,L35,M31,M32,M33,M34,M35,N31,N32,N33,N34,N35,O31,O32,O33,O34,O35],
	      [K41,K42,K43,K44,K45,L41,L42,L43,L44,L45,M41,M42,M43,M44,M45,N41,N42,N43,N44,N45,O41,O42,O43,O44,O45],
	      [K51,K52,K53,K54,K55,L51,L52,L53,L54,L55,M51,M52,M53,M54,M55,N51,N52,N53,N54,N55,O51,O52,O53,O54,O55],
	      [P11,P12,P13,P14,P15,Q11,Q12,Q13,Q14,Q15,R11,R12,R13,R14,R15,S11,S12,S13,S14,S15,T11,T12,T13,T14,T15],
	      [P21,P22,P23,P24,P25,Q21,Q22,Q23,Q24,Q25,R21,R22,R23,R24,R25,S21,S22,S23,S24,S25,T21,T22,T23,T24,T25],
	      [P31,P32,P33,P34,P35,Q31,Q32,Q33,Q34,Q35,R31,R32,R33,R34,R35,S31,S32,S33,S34,S35,T31,T32,T33,T34,T35],
	      [P41,P42,P43,P44,P45,Q41,Q42,Q43,Q44,Q45,R41,R42,R43,R44,R45,S41,S42,S43,S44,S45,T41,T42,T43,T44,T45],
	      [P51,P52,P53,P54,P55,Q51,Q52,Q53,Q54,Q55,R51,R52,R53,R54,R55,S51,S52,S53,S54,S55,T51,T52,T53,T54,T55],
	      [U11,U12,U13,U14,U15,V11,V12,V13,V14,V15,W11,W12,W13,W14,W15,X11,X12,X13,X14,X15,Y11,Y12,Y13,Y14,Y15],
	      [U21,U22,U23,U24,U25,V21,V22,V23,V24,V25,W21,W22,W23,W24,W25,X21,X22,X23,X24,X25,Y21,Y22,Y23,Y24,Y25],
	      [U31,U32,U33,U34,U35,V31,V32,V33,V34,V35,W31,W32,W33,W34,W35,X31,X32,X33,X34,X35,Y31,Y32,Y33,Y34,Y35],
	      [U41,U42,U43,U44,U45,V41,V42,V43,V44,V45,W41,W42,W43,W44,W45,X41,X42,X43,X44,X45,Y41,Y42,Y43,Y44,Y45],
	      [U51,U52,U53,U54,U55,V51,V52,V53,V54,V55,W51,W52,W53,W54,W55,X51,X52,X53,X54,X55,Y51,Y52,Y53,Y54,Y55]],
    array_to_list(AVars,Vars1),
    reverse(Vars1,Vars),
    domain(Vars,0,24),
    A11#=2,A12#=1,A14#=13,B11#=0,B15#=10,C12#=12,D13#=6,D15#=15,E11#=14,E13#=20,E14#=8,A25#=24,B21#=20,B22#=11,C21#=16,C24#=6,D21#=21,E22#=17,E25#=1,A32#=21,A33#=9,A35#=10,B31#=4,B34#=12,C33#=11,C35#=22,D33#=2,A41#=6,A43#=3,A44#=16,B41#=13,B44#=5,C43#=21,C44#=23,C45#=10,D41#=11,D42#=14,D43#=8,E42#=24,E45#=7,A51#=8,A54#=20,A55#=22,B51#=16,B54#=3,C52#=5,D53#=18,D54#=4,D55#=24,E52#=10,E53#=0,F12#=23,F14#=9,G11#=12,H11#=14,H13#=8,H14#=22,H15#=20,I15#=13,J14#=15,F24#=14,G21#=3,G24#=19,H23#=2,H25#=13,I21#=18,I22#=7,I25#=4,G33#=17,G34#=1,G35#=13,H31#=9,I34#=14,J32#=4,J33#=12,F42#=2,G42#=23,G43#=10,G44#=21,H42#=7,H44#=24,I42#=19,I45#=16,J44#=22,J45#=8,F52#=18,F55#=4,G54#=11,H51#=3,H53#=6,H54#=15,H55#=16,I53#=10,J51#=1,J53#=5,K12#=3,K13#=16,K14#=15,L11#=17,L12#=5,M12#=0,M15#=23,N14#=22,O11#=4,O13#=24,O14#=7,K22#=12,K24#=24,L21#=22,L22#=14,L25#=8,M22#=16,M23#=3,M25#=6,N21#=9,O21#=13,O22#=2,O23#=17,K31#=1,K32#=5,K33#=13,L31#=10,L32#=9,L33#=21,M35#=18,N31#=3,O31#=20,O32#=8,K43#=0,K44#=10,K45#=23,L44#=4,L45#=18,M44#=11,N43#=1,N44#=17,N45#=2,O42#=6,O43#=15,O44#=19,O45#=3,K51#=11,K52#=14,K53#=20,K54#=22,L51#=15,L55#=6,M52#=13,M54#=1,N51#=12,N53#=7,O51#=0,O53#=10,O55#=9,P12#=15,Q13#=13,Q14#=2,R12#=23,R15#=9,S13#=20,S15#=14,Q22#=15,R23#=17,R24#=13,S22#=18,S25#=12,T23#=21,T25#=10,P31#=0,Q31#=7,Q34#=18,R31#=11,R33#=22,R35#=14,S35#=5,T31#=6,T34#=16,T35#=15,P44#=1,P45#=5,Q43#=0,Q44#=23,Q45#=9,R41#=7,R43#=24,S42#=6,S44#=19,P54#=7,Q52#=22,Q53#=20,Q54#=8,Q55#=14,R51#=19,R55#=3,S52#=23,S53#=0,T53#=1,T55#=17,U15#=11,V11#=6,V13#=3,V15#=19,W11#=2,W12#=17,W14#=5,X14#=18,Y12#=21,Y14#=9,U22#=16,U23#=15,U24#=6,U25#=19,V21#=2,V25#=1,W23#=0,W24#=9,X22#=22,X25#=11,Y23#=18,Y24#=12,Y25#=4,U33#=10,V31#=18,V33#=12,V35#=7,W31#=8,W33#=20,X32#=17,X33#=5,X34#=2,Y31#=15,Y32#=19,Y33#=6,Y34#=3,U43#=17,V43#=9,W41#=18,W42#=24,W43#=4,W44#=12,X41#=16,X42#=15,X43#=3,X45#=19,Y42#=11,Y45#=20,U53#=24,U55#=7,V51#=8,V52#=20,V55#=11,W52#=15,X51#=0,X52#=10,X54#=23,X55#=21,Y55#=13,

    %
    sudoku_alldistinct(AVars),
    labeling_ff(Vars),
    visualizeSudoku(AVars,Os).
    
sudoku("Sudoku378",Os):-
    new_array(AVars,[25,25]),
    AVars @= [[A11,A12,A13,A14,A15,B11,B12,B13,B14,B15,C11,C12,C13,C14,C15,D11,D12,D13,D14,D15,E11,E12,E13,E14,E15],
	      [A21,A22,A23,A24,A25,B21,B22,B23,B24,B25,C21,C22,C23,C24,C25,D21,D22,D23,D24,D25,E21,E22,E23,E24,E25],
	      [A31,A32,A33,A34,A35,B31,B32,B33,B34,B35,C31,C32,C33,C34,C35,D31,D32,D33,D34,D35,E31,E32,E33,E34,E35],
	      [A41,A42,A43,A44,A45,B41,B42,B43,B44,B45,C41,C42,C43,C44,C45,D41,D42,D43,D44,D45,E41,E42,E43,E44,E45],
	      [A51,A52,A53,A54,A55,B51,B52,B53,B54,B55,C51,C52,C53,C54,C55,D51,D52,D53,D54,D55,E51,E52,E53,E54,E55],
	      [F11,F12,F13,F14,F15,G11,G12,G13,G14,G15,H11,H12,H13,H14,H15,I11,I12,I13,I14,I15,J11,J12,J13,J14,J15],
	      [F21,F22,F23,F24,F25,G21,G22,G23,G24,G25,H21,H22,H23,H24,H25,I21,I22,I23,I24,I25,J21,J22,J23,J24,J25],
	      [F31,F32,F33,F34,F35,G31,G32,G33,G34,G35,H31,H32,H33,H34,H35,I31,I32,I33,I34,I35,J31,J32,J33,J34,J35],
	      [F41,F42,F43,F44,F45,G41,G42,G43,G44,G45,H41,H42,H43,H44,H45,I41,I42,I43,I44,I45,J41,J42,J43,J44,J45],
	      [F51,F52,F53,F54,F55,G51,G52,G53,G54,G55,H51,H52,H53,H54,H55,I51,I52,I53,I54,I55,J51,J52,J53,J54,J55],
	      [K11,K12,K13,K14,K15,L11,L12,L13,L14,L15,M11,M12,M13,M14,M15,N11,N12,N13,N14,N15,O11,O12,O13,O14,O15],
	      [K21,K22,K23,K24,K25,L21,L22,L23,L24,L25,M21,M22,M23,M24,M25,N21,N22,N23,N24,N25,O21,O22,O23,O24,O25],
	      [K31,K32,K33,K34,K35,L31,L32,L33,L34,L35,M31,M32,M33,M34,M35,N31,N32,N33,N34,N35,O31,O32,O33,O34,O35],
	      [K41,K42,K43,K44,K45,L41,L42,L43,L44,L45,M41,M42,M43,M44,M45,N41,N42,N43,N44,N45,O41,O42,O43,O44,O45],
	      [K51,K52,K53,K54,K55,L51,L52,L53,L54,L55,M51,M52,M53,M54,M55,N51,N52,N53,N54,N55,O51,O52,O53,O54,O55],
	      [P11,P12,P13,P14,P15,Q11,Q12,Q13,Q14,Q15,R11,R12,R13,R14,R15,S11,S12,S13,S14,S15,T11,T12,T13,T14,T15],
	      [P21,P22,P23,P24,P25,Q21,Q22,Q23,Q24,Q25,R21,R22,R23,R24,R25,S21,S22,S23,S24,S25,T21,T22,T23,T24,T25],
	      [P31,P32,P33,P34,P35,Q31,Q32,Q33,Q34,Q35,R31,R32,R33,R34,R35,S31,S32,S33,S34,S35,T31,T32,T33,T34,T35],
	      [P41,P42,P43,P44,P45,Q41,Q42,Q43,Q44,Q45,R41,R42,R43,R44,R45,S41,S42,S43,S44,S45,T41,T42,T43,T44,T45],
	      [P51,P52,P53,P54,P55,Q51,Q52,Q53,Q54,Q55,R51,R52,R53,R54,R55,S51,S52,S53,S54,S55,T51,T52,T53,T54,T55],
	      [U11,U12,U13,U14,U15,V11,V12,V13,V14,V15,W11,W12,W13,W14,W15,X11,X12,X13,X14,X15,Y11,Y12,Y13,Y14,Y15],
	      [U21,U22,U23,U24,U25,V21,V22,V23,V24,V25,W21,W22,W23,W24,W25,X21,X22,X23,X24,X25,Y21,Y22,Y23,Y24,Y25],
	      [U31,U32,U33,U34,U35,V31,V32,V33,V34,V35,W31,W32,W33,W34,W35,X31,X32,X33,X34,X35,Y31,Y32,Y33,Y34,Y35],
	      [U41,U42,U43,U44,U45,V41,V42,V43,V44,V45,W41,W42,W43,W44,W45,X41,X42,X43,X44,X45,Y41,Y42,Y43,Y44,Y45],
	      [U51,U52,U53,U54,U55,V51,V52,V53,V54,V55,W51,W52,W53,W54,W55,X51,X52,X53,X54,X55,Y51,Y52,Y53,Y54,Y55]],
    array_to_list(AVars,Vars),
    domain(Vars,0,24),
    E21#=4,E22#=20,E23#=21,E24#=3,E25#=5,D31#=18,D32#=16,D33#=7,D34#=24,D35#=9,E31#=23,E32#=13,E33#=0,E34#=12,E35#=19,C41#=4,C42#=5,C43#=21,C44#=20,C45#=3,D41#=17,D42#=10,D43#=2,D44#=6,D45#=1,B51#=5,B52#=4,B53#=20,B54#=3,B55#=21,C51#=2,C52#=17,C53#=6,C54#=10,C55#=1,D51#=8,D52#=14,D53#=15,D54#=22,D55#=11,F15#=12,J15#=24,F25#=9,G25#=12,J21#=8,J22#=15,J24#=14,F35#=11,G35#=9,H35#=13,I31#=21,I32#=4,I33#=5,I35#=20,J31#=17,J32#=2,J35#=6,F45#=3,G45#=1,H41#=8,H42#=22,H44#=15,I41#=24,I42#=7,I43#=18,I45#=16,J43#=12,J44#=13,F55#=1,G51#=22,G52#=8,G53#=15,G54#=14,H51#=18,H52#=24,H54#=7,H55#=16,I51#=0,I52#=23,I53#=19,I54#=12,I55#=13,J53#=3,J54#=20,K14#=11,K15#=14,L14#=7,L15#=16,M14#=19,M15#=23,N15#=4,O14#=2,O15#=1,K24#=1,K25#=10,L25#=14,M25#=7,N25#=23,O21#=21,K34#=12,K35#=13,L35#=20,M31#=6,N31#=11,N32#=8,N33#=22,O32#=18,O33#=16,O35#=9,K44#=9,K45#=16,L44#=23,L45#=13,M44#=5,N42#=17,N43#=6,O44#=15,O45#=11,K54#=3,K55#=20,L52#=6,L53#=17,M51#=22,M52#=11,N51#=9,N52#=18,N53#=24,N54#=16,N55#=7,O52#=19,O53#=13,P13#=8,P14#=14,P15#=15,Q13#=24,Q14#=18,R13#=23,R14#=0,R15#=19,S13#=3,T15#=10,P23#=18,P24#=16,P25#=7,Q23#=0,Q24#=19,R24#=21,R25#=5,S24#=2,S25#=17,T25#=14,P33#=19,P34#=13,P35#=23,Q34#=5,Q35#=4,R34#=6,R35#=17,S33#=11,S34#=15,T31#=9,T33#=7,T35#=16,P43#=5,P44#=20,P45#=4,Q43#=6,Q44#=17,Q45#=2,R41#=11,R44#=22,R45#=8,S41#=16,S42#=24,S43#=9,T41#=12,T43#=23,P53#=17,P54#=10,P55#=2,Q52#=11,Q55#=15,R51#=9,R52#=16,S51#=13,S52#=0,S53#=12,T51#=3,T52#=21,T53#=4,U12#=10,U13#=6,V13#=11,V14#=22,W13#=18,W14#=9,X13#=13,X15#=0,Y15#=4,U22#=20,U23#=21,V22#=10,V23#=1,V24#=6,W22#=15,W24#=11,Y25#=23,U32#=13,U33#=0,V33#=3,V34#=21,W33#=17,W34#=1,W35#=6,X31#=15,X34#=8,Y31#=16,Y34#=24,Y35#=7,U42#=16,U43#=24,V42#=13,V43#=12,V45#=19,W41#=20,W42#=4,X41#=2,X42#=1,X44#=17,Y41#=14,Y43#=8,Y44#=22,U52#=14,U53#=22,V51#=7,V53#=9,V54#=24,V55#=18,W52#=23,W53#=19,W54#=12,X52#=3,X53#=20,X54#=5,Y52#=1,Y54#=6,Y55#=2,
    %
    sudoku_alldistinct(AVars),
    labeling_ff(Vars),
    visualizeSudoku(AVars,Os).
    
sudoku_alldistinct(AVars):-
    AVars^length @= N,
    sudoku_alldistinct_row(AVars,1,N),
    sudoku_alldistinct_col(AVars,1,N),
    sudoku_alldistinct_square(AVars,1,1,N).
    
sudoku_alldistinct_row(AVars,N0,N):-N0>N,!.
sudoku_alldistinct_row(AVars,N0,N):-
    AVars^[N0] @= Row,
    array_to_list(Row,Vars),
    all_distinct(Vars),
    N1 is N0+1,
    sudoku_alldistinct_row(AVars,N1,N).

sudoku_alldistinct_col(AVars,N0,N):-N0>N,!.
sudoku_alldistinct_col(AVars,N0,N):-
    extract_col(AVars,N0,1,N,Vars),
    all_distinct(Vars),
    N1 is N0+1,
    sudoku_alldistinct_col(AVars,N1,N).

extract_col(AVars,I,J,N,Vars):-J>N,!,Vars=[].
extract_col(AVars,I,J,N,Vars):-
    AVars^[I,J] @= Var,
    Vars=[Var|VarsR],
    J1 is J+1,
    extract_col(AVars,I,J1,N,VarsR).

sudoku_alldistinct_square(AVars,I,J,N):-J>N,!.
sudoku_alldistinct_square(AVars,I,J,N):-I>N,!,
    J1 is J+floor(sqrt(N)),
    sudoku_alldistinct_square(AVars,1,J1,N).
sudoku_alldistinct_square(AVars,I,J,N):-
    I1 is I+floor(sqrt(N)),
    J1 is J+floor(sqrt(N)),
    extract_square(AVars,I,J,I,I1,J,J1,Vars),
    all_distinct(Vars),
    sudoku_alldistinct_square(AVars,I1,J,N).
    
extract_square(AVars,I0,J0,I,MaxI,J,MaxJ,Vars):-J>=MaxJ,!,Vars=[].
extract_square(AVars,I0,J0,I,MaxI,J,MaxJ,Vars):-I>=MaxI,!,
    J1 is J+1,
    extract_square(AVars,I0,J0,I0,MaxI,J1,MaxJ,Vars).
extract_square(AVars,I0,J0,I,MaxI,J,MaxJ,Vars):-    
    AVars^[I,J] @= Var,
    Vars=[Var|VarsR],
    I1 is I+1,
    extract_square(AVars,I0,J0,I1,MaxI,J,MaxJ,VarsR).
    
%%
visualizeSudoku(AVars,Os):-
    AVars^length @= N,
    new_array(Board,[N,N]),
    createButtons(AVars,Board,1,1,N),
    cgGrid(Board),
    array_to_list(Board,Os).

createButtons(AVars,Board,I,J,N):-J>N,!.
createButtons(AVars,Board,I,J,N):-I>N,!,
    J1 is J+1,
    createButtons(AVars,Board,1,J1,N).
createButtons(AVars,Board,I,J,N):-
    AVars^[I,J] @= Num,
    number_codes(Num,String),
    cgButton(B,String),
    Board^[I,J] @= B,
    I1 is I+1,
    createButtons(AVars,Board,I1,J,N).
    
