/* Sudoku solver. (C) Andrea Sterbini Released under the GNU licence. */ :- initialization(go). go :- header, Righe = [ [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _], [ _, _, _, _, _, _, _, _, _] ], groups(Puzzle, _Groups, Righe, _Quadrati), vincola_puzzle(Puzzle), leggi_righe(Righe), format("... hmmm ... sto cercando una soluzione ... vediamo ...~n" , []), % sleep(5), ( fd_labeling(Puzzle) -> format("Eccola!!!~n" , []), print_puzzle(Righe) ; format("Non esiste una soluzione!!!~n", [])), footer, halt. header :- format("~n\ Sudoku solver. (C) Andrea Sterbini ~n\ Released under the GNU licence.~n\ ~n\ Istruzioni: inserite i numeri del Sudoku~n\ usando il carattere '.' (punto) ~n\ per le posizioni vuote (sconosciute).~n\ Nota: il programma non accetta valori inconsistenti.~n\ ", []). footer :- format("A presto.~n", []). vincola_puzzle( Puzzle ) :- groups(Puzzle, Groups, _Righe, _Quadrati), vincola_valori(Puzzle), vincola_gruppi(Groups). groups( Puzzle, Groups, Righe, Quadrati ) :- Puzzle = [ A1, A2, A3, A4, A5, A6, A7, A8, A9 , B1, B2, B3, B4, B5, B6, B7, B8, B9 , C1, C2, C3, C4, C5, C6, C7, C8, C9 , D1, D2, D3, D4, D5, D6, D7, D8, D9 , E1, E2, E3, E4, E5, E6, E7, E8, E9 , F1, F2, F3, F4, F5, F6, F7, F8, F9 , G1, G2, G3, G4, G5, G6, G7, G8, G9 , H1, H2, H3, H4, H5, H6, H7, H8, H9 , I1, I2, I3, I4, I5, I6, I7, I8, I9 ], Groups = [ /* righe */ [ A1, A2, A3, A4, A5, A6, A7, A8, A9], [ B1, B2, B3, B4, B5, B6, B7, B8, B9], [ C1, C2, C3, C4, C5, C6, C7, C8, C9], [ D1, D2, D3, D4, D5, D6, D7, D8, D9], [ E1, E2, E3, E4, E5, E6, E7, E8, E9], [ F1, F2, F3, F4, F5, F6, F7, F8, F9], [ G1, G2, G3, G4, G5, G6, G7, G8, G9], [ H1, H2, H3, H4, H5, H6, H7, H8, H9], [ I1, I2, I3, I4, I5, I6, I7, I8, I9], /* colonne */ [ A1, B1, C1, D1, E1, F1, G1, H1, I1], [ A2, B2, C2, D2, E2, F2, G2, H2, I2], [ A3, B3, C3, D3, E3, F3, G3, H3, I3], [ A4, B4, C4, D4, E4, F4, G4, H4, I4], [ A5, B5, C5, D5, E5, F5, G5, H5, I5], [ A6, B6, C6, D6, E6, F6, G6, H6, I6], [ A7, B7, C7, D7, E7, F7, G7, H7, I7], [ A8, B8, C8, D8, E8, F8, G8, H8, I8], [ A9, B9, C9, D9, E9, F9, G9, H9, I9], /* quadranti */ [ A1, A2, A3, B1, B2, B3, C1, C2, C3], [ A4, A5, A6, B4, B5, B6, C4, C5, C6], [ A7, A8, A9, B7, B8, B9, C7, C8, C9], [ D1, D2, D3, E1, E2, E3, F1, F2, F3], [ D4, D5, D6, E4, E5, E6, F4, F5, F6], [ D7, D8, D9, E7, E8, E9, F7, F8, F9], [ G1, G2, G3, H1, H2, H3, I1, I2, I3], [ G4, G5, G6, H4, H5, H6, I4, I5, I6], [ G7, G8, G9, H7, H8, H9, I7, I8, I9] ], Righe = [ [ A1, A2, A3, A4, A5, A6, A7, A8, A9], [ B1, B2, B3, B4, B5, B6, B7, B8, B9], [ C1, C2, C3, C4, C5, C6, C7, C8, C9], [ D1, D2, D3, D4, D5, D6, D7, D8, D9], [ E1, E2, E3, E4, E5, E6, E7, E8, E9], [ F1, F2, F3, F4, F5, F6, F7, F8, F9], [ G1, G2, G3, G4, G5, G6, G7, G8, G9], [ H1, H2, H3, H4, H5, H6, H7, H8, H9], [ I1, I2, I3, I4, I5, I6, I7, I8, I9] ], Quadrati = [ [ A1, A2, A3, B1, B2, B3, C1, C2, C3], [ A4, A5, A6, B4, B5, B6, C4, C5, C6], [ A7, A8, A9, B7, B8, B9, C7, C8, C9], [ D1, D2, D3, E1, E2, E3, F1, F2, F3], [ D4, D5, D6, E4, E5, E6, F4, F5, F6], [ D7, D8, D9, E7, E8, E9, F7, F8, F9], [ G1, G2, G3, H1, H2, H3, I1, I2, I3], [ G4, G5, G6, H4, H5, H6, I4, I5, I6], [ G7, G8, G9, H7, H8, H9, I7, I8, I9] ]. vincola_valori(Puzzle) :- fd_domain(Puzzle, 1, 9). vincola_gruppi([]) :- !. vincola_gruppi([H|T]) :- fd_all_different(H), vincola_gruppi(T). leggi_righe([A,B,C,D,E,F,G,H,I]) :- format("~s", ["|-------|-------|-------|\n"]), leggi_riga(A), leggi_riga(B), leggi_riga(C), format("~s", ["|-------|-------|-------|\n"]), leggi_riga(D), leggi_riga(E), leggi_riga(F), format("~s", ["|-------|-------|-------|\n"]), leggi_riga(G), leggi_riga(H), leggi_riga(I), format("~s", ["|-------|-------|-------|\n"]). leggi_riga([A,B,C,D,E,F,G,H,I]) :- format("~s", ["| "]), leggi_valore(A), format("~s", [" "]), leggi_valore(B), format("~s", [" "]), leggi_valore(C), format("~s", [" | "]), leggi_valore(D), format("~s", [" "]), leggi_valore(E), format("~s", [" "]), leggi_valore(F), format("~s", [" | "]), leggi_valore(G), format("~s", [" "]), leggi_valore(H), format("~s", [" "]), leggi_valore(I), format("~s", [" |\n"]). leggi_valore(H) :- repeat, get_key(C), (member(C, [46, 49, 50, 51, 52, 53, 54, 55, 56, 57]) -> true ; format("~c!~c",[8,8]), % beep, fail ), (C \= 46 -> (H #= C - 48 -> true ; % beep, format("~c!~c",[8,8]), fail) ; true) , !. print_puzzle([A,B,C,D,E,F,G,H,I]) :- format("~s", ["|-------|-------|-------|\n"]), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",A), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",B), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",C), format("~s", ["|-------|-------|-------|\n"]), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",D), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",E), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",F), format("~s", ["|-------|-------|-------|\n"]), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",G), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",H), format("| ~d ~d ~d | ~d ~d ~d | ~d ~d ~d |\n",I), format("~s", ["|-------|-------|-------|\n"]).