66
|
1 % Create a generic sudoku reader
|
|
2
|
|
3 valid([]).
|
|
4 valid([Head|Tail]) :-
|
|
5 fd_all_different(Head),
|
|
6 valid(Tail).
|
|
7
|
|
8 sudoku(Board, X, Y, Solution) :-
|
|
9 Solution = Board,
|
|
10 Max is X * Y,
|
|
11 fd_domain(Solution, 1, Max),
|
|
12 board(X, Y, Board),
|
|
13 rows(Board, Max, Rows),
|
|
14 cols(Board, Max, Cols),
|
|
15 valid(Rows),
|
|
16 valid(Cols).
|
|
17 % TODO: Calculate boxes and validate them
|
|
18
|
|
19 board(X, Y, Board) :-
|
|
20 Size is X * Y * X * Y,
|
|
21 board(Size, Board).
|
|
22 board(1, [_]).
|
|
23 board(Size, [_|Board]) :- SmallerSize is Size - 1, board(SmallerSize, Board).
|
|
24
|
|
25 sublist(Start, Length, Input, Output) :- End is Start + Length - 1, sublist(Start, End, 1, Input, Output).
|
|
26 sublist(Start, End, Pos, [Head|TailIn], [Head|TailOut]) :- Pos >= Start, Pos =< End, NextPos is Pos + 1, sublist(Start, End, NextPos, TailIn, TailOut).
|
|
27 sublist(Start, End, Pos, [_|TailIn], Output) :- Pos < Start, NextPos is Pos + 1, sublist(Start, End, NextPos, TailIn, Output).
|
|
28 sublist(_, End, Pos, _, []) :- Pos > End.
|
|
29
|
|
30 rows(Board, RowLength, Rows) :- rows(Board, RowLength, 1, Rows).
|
|
31 rows(Board, RowLength, RowNum, [NewRow|Rows]) :- RowNum =< RowLength, NextRowNum is RowNum + 1,
|
|
32 Start is ((RowNum - 1) * RowLength) + 1, sublist(Start, RowLength, Board, NewRow),
|
|
33 rows(Board, RowLength, NextRowNum, Rows).
|
|
34 rows(_, RowLength, RowNum, []) :- RowNum > RowLength.
|
|
35
|
|
36 nth_from_list(Start, N, Input, Output) :- nth_from_list(N, Start, 1, Input, Output).
|
|
37 nth_from_list(N, Next, Pos, [Head|TailIn], [Head|TailOut]) :- Pos == Next, NewNext is Next + N, NewPos is Pos + 1,
|
|
38 nth_from_list(N, NewNext, NewPos, TailIn, TailOut).
|
|
39 nth_from_list(N, Next, Pos, [_|TailIn], Output) :- NewPos is Pos + 1, nth_from_list(N, Next, NewPos, TailIn, Output).
|
|
40 nth_from_list(_, _, _, [], []).
|
|
41
|
|
42 cols(Board, ColLength, Cols) :- cols(Board, ColLength, 1, Cols).
|
|
43 cols(Board, ColLength, ColNum, [NewCol|Cols]) :- ColNum =< ColLength, NextColNum is ColNum + 1,
|
|
44 nth_from_list(ColNum, ColLength, Board, NewCol),
|
|
45 cols(Board, ColLength, NextColNum, Cols).
|
|
46 cols(_, ColLength, ColNum, []) :- ColNum > ColLength. |