-
Notifications
You must be signed in to change notification settings - Fork 1
/
sudoku.pl
71 lines (54 loc) · 1.55 KB
/
sudoku.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
% vim:ft=prolog
maplist(F, []).
maplist(F, [X | Xs]) :- call(F, X), maplist(F, Xs).
maplist(F, [], []).
maplist(F, [X | Xs], [Y | Ys]) :- call(F, X, Y), maplist(F, Xs, Ys).
same_length([], []).
same_length([_ | X], [_ | Y]) :- same_length(X, Y).
length([], 0).
length([_ | Tail], N) :- length(Tail, N1), N is N1 + 1.
member(X, [X | _]).
member(X, [_ | Tail]) :- member(X, Tail).
head([X | _], X).
tail([_ | X], X).
all_distinct([X | Xs]) :- \+ member(X, Xs), all_distinct(Xs).
all_distinct([]).
transpose([], []).
transpose([[] | Xss], Yss) :- transpose(Xss, Yss).
transpose(Xss, [Ys | Yss]) :- Xss = [_|_],
maplist(head, Xss, Ys), maplist(tail, Xss, Tails),
transpose(Tails, Yss).
upto(X, X, [X]).
upto(X, Y, [X | Tail]) :- X \= Y, X1 is X + 1, upto(X1, Y, Tail).
time(Goal) :-
cpu_time(Start),
Goal,
cpu_time(End),
Duration is End - Start,
nl, write('Took '), write(Duration), write('ms'), nl.
%%%%%
in_range(1).
in_range(2).
in_range(3).
in_range(4).
good_row(Row) :- maplist(in_range, Row), all_distinct(Row).
mini_sudoku(Rows) :-
length(Rows,4), maplist(same_length(Rows), Rows),
transpose(Rows, Cols),
Rows = [As,Bs,Cs,Ds],
maplist(good_row, Rows),
maplist(all_distinct, Cols),
blocks(As, Bs),
blocks(Cs, Ds).
blocks([], []).
blocks([N1,N2|Ns1], [N3,N4|Ns2]) :-
all_distinct([N1,N2,N3,N4]),
blocks(Ns1, Ns2).
problem(1, [[_,2,_,_],
[_,_,1,_],
[_,1,_,_],
[_,_,4,_]]).
problem(2, [[1,_,2,_],
[_,2,_,_],
[_,_,3,_],
[_,_,_,_]]).