% Sudoku solver v CLP, pro libovolně velké sudoku % (c) 2014 Vladimír Štill % BSD2 licenced :- use_module(library(clpfd)). % vyres sudoku o delce hrany N^2 (tj. N je pocet poctvercu v sudoku) % sudoku(3, X) generuje reseni standartiniho 9*9 sudoku sudoku(N, X) :- N2 is N * N, length(X, N2), sub_length(X, N2), flatten(X, FX), % ins & label potrebuje seznam promennych, ne seznam seznamu FX ins 1..N2, sub_different(X), cols_different(N2, X), squares_diff(N, X), label(FX). sub_length([], _) :- !. sub_length([X|XS], N) :- length(X, N), sub_length(XS, N). sub_different([]) :- !. sub_different([X|XS]) :- all_different(X), sub_different(XS). cols_different(0, _) :- !. cols_different(N, XS) :- pick_nth(N, XS, ES), all_different(ES), N1 is N - 1, cols_different(N1, XS). pick_nth(_, [], []) :- !. pick_nth(N, [X|XS], [E|ES]) :- nth1(N, X, E), pick_nth(N, XS, ES). squares_diff(N, Rows) :- squares_diff2(N, N, N, Rows). squares_diff2(0, _SY, _, _) :- !. squares_diff2(SX, 0, N, Rows) :- !, SX1 is SX - 1, squares_diff2(SX1, N, N, Rows). squares_diff2(SX, SY, N, Rows) :- square(SX, SY, N, N, N, Rows, Square), all_different(Square), SY1 is SY - 1, squares_diff2(SX, SY1, N, Rows). square(_, _, 0, _Yi, _, _, []) :- !. square(SX, SY, Xi, 0, N, Rows, XS) :- !, Xi1 is Xi - 1, square(SX, SY, Xi1, N, N, Rows, XS). square(SX, SY, Xi, Yi, N, Rows, [X|XS]) :- Xix is N * (SX - 1) + Xi, Yix is N * (SY - 1) + Yi, nth1(Xix, Rows, Row), nth1(Yix, Row, X), Yi1 is Yi - 1, square(SX, SY, Xi, Yi1, N, Rows, XS).