% sudoku.pl

:- use_module(library(clpfd)).


main( N ) :-
        problem(N, Rows), 
        sudoku(Rows), 
        maplist(writeln, Rows).

sudoku(Rows) :-
        length(Rows, 9), maplist(length_(9), Rows),
        append(Rows, Vs), Vs ins 1..9,
        maplist(all_distinct, Rows),
        transpose(Rows, Columns),
        maplist(all_distinct, Columns),
        Rows = [A,B,C,D,E,F,G,H,I],
        blocks(A, B, C), blocks(D, E, F), blocks(G, H, I).

length_(L, Ls) :- length(Ls, L).

blocks([], [], []).
blocks([A,B,C|Bs1], [D,E,F|Bs2], [G,H,I|Bs3]) :-
        all_distinct([A,B,C,D,E,F,G,H,I]),
        blocks(Bs1, Bs2, Bs3).

% 解は１つ。求まります。
problem(1, [[_,_,_,_,_,_,_,_,_],
            [_,_,_,_,_,3,_,8,5],
            [_,_,1,_,2,_,_,_,_],
            [_,_,_,5,_,7,_,_,_],
            [_,_,4,_,_,_,1,_,_],
            [_,9,_,_,_,_,_,_,_],
            [5,_,_,_,_,_,_,7,3],
            [_,_,2,_,1,_,_,_,_],
            [_,_,_,_,4,_,_,_,9]]).

% 解は１つ。求まります。
problem(2, [[_,_,9,_,_,_,_,_,_],
            [_,_,5,_,_,4,_,_,_],
            [_,_,7,_,_,6,_,_,1],
            [4,_,_,_,_,9,_,_,7],
            [2,_,_,_,_,_,_,_,8],
            [3,_,_,6,_,_,_,_,2],
            [7,_,_,2,_,_,4,_,_],
            [_,_,_,8,_,_,9,_,_],
            [_,_,_,_,_,_,2,_,_]]).

% 解が２つの問題
problem(3, [[_,_,5,_,_,_,3,_,_],
            [_,8,_,1,_,7,_,2,_],
            [3,_,_,_,6,_,_,_,9],
            [_,9,_,6,_,3,_,4,_],
            [_,_,1,_,_,_,6,_,_],
            [_,5,_,8,_,2,_,9,_],
            [2,_,_,_,7,_,_,_,5],
            [_,1,_,4,_,5,_,6,_],
            [_,_,4,_,_,_,9,_,_]]).


%  解が無い問題
problem(4, [[_,_,5,_,_,_,3,_,_],
            [_,8,_,1,_,7,_,2,_],
            [3,_,_,_,6,_,_,_,9],
            [_,9,_,6,_,3,_,4,_],
            [_,_,1,_,_,_,6,_,_],
            [_,5,_,8,_,2,_,9,_],
            [2,_,_,_,7,_,_,_,3],
            [_,1,_,4,_,5,_,6,_],
            [_,_,4,_,_,_,9,_,_]]).


