Skip to content

Instantly share code, notes, and snippets.

@brikis98
Created February 15, 2012 10:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brikis98/1834944 to your computer and use it in GitHub Desktop.
Save brikis98/1834944 to your computer and use it in GitHub Desktop.
Seven Languages in Seven Weeks: Prolog, Day 3
slice([Head | Tail], Slice, Size, Type, I) :-
slice_position(Type, Size, I, X, Y),
insert_into_slice(Head, Slice, X, Y),
I1 is I + 1,
slice(Tail, Slice, Size, Type, I1).
slice_position('row', Size, I, X, Y) :-
X is I // Size,
Y is I mod Size.
slice_position('square', Size, I, X, Y) :-
Size_Sqrt is floor(sqrt(Size)),
X is (I mod Size // Size_Sqrt) + (Size_Sqrt * (I // (Size * Size_Sqrt))),
Y is (I mod Size_Sqrt) + (Size_Sqrt * ((I mod (Size * Size_Sqrt)) // Size)).
sudoku(Puzzle, Solution) :-
length(Puzzle, L),
Size is floor(sqrt(L)),
Solution = Puzzle,
fd_domain(Solution, 1, Size),
slice(Puzzle, Rows, Size, 'row'),
slice(Puzzle, Cols, Size, 'col'),
slice(Puzzle, Squares, Size, 'square'),
valid(Rows),
valid(Cols),
valid(Squares),
pretty_print(Rows).
valid([]).
valid([Head | Tail]) :- fd_all_different(Head), valid(Tail).
sublist_length([], _).
sublist_length([Head | Tail], Length) :- length(Head, Length), sublist_length(Tail, Length).
nth0(I, List, Out) :- I1 is I + 1, nth(I1, List, Out).
insert_into_slice(Item, Values, X, Y) :-
nth0(X, Values, Bucket),
nth0(Y, Bucket, Item).
slice_position('row', Size, I, X, Y) :-
X is I // Size,
Y is I mod Size.
slice_position('col', Size, I, X, Y) :-
X is I mod Size,
Y is I // Size.
slice_position('square', Size, I, X, Y) :-
Size_Sqrt is floor(sqrt(Size)),
X is (I mod Size // Size_Sqrt) + (Size_Sqrt * (I // (Size * Size_Sqrt))),
Y is (I mod Size_Sqrt) + (Size_Sqrt * ((I mod (Size * Size_Sqrt)) // Size)).
slice(Puzzle, Slice, Size, Type) :- slice(Puzzle, Slice, Size, Type, 0).
slice(_, Slice, Size, _, I) :- I is Size * Size, length(Slice, Size), sublist_length(Slice, Size).
slice([Head | Tail], Slice, Size, Type, I) :-
slice_position(Type, Size, I, X, Y),
insert_into_slice(Head, Slice, X, Y),
I1 is I + 1,
slice(Tail, Slice, Size, Type, I1).
pretty_print([Head | Tail]) :-
print(Head),
print('\n'),
pretty_print(Tail).
sudoku(Puzzle, Solution) :-
Solution = Puzzle,
Puzzle = [S11, S12, S13, S14,
S21, S22, S23, S24,
S31, S32, S33, S34,
S41, S42, S43, S44],
fd_domain(Solution, 1, 4),
Row1 = [S11, S12, S13, S14],
Row2 = [S21, S22, S23, S24],
Row3 = [S31, S32, S33, S34],
Row4 = [S41, S42, S43, S44],
Col1 = [S11, S21, S31, S41],
Col2 = [S12, S22, S32, S42],
Col3 = [S13, S23, S33, S43],
Col4 = [S14, S24, S34, S44],
Square1 = [S11, S12, S21, S22],
Square2 = [S13, S14, S23, S24],
Square3 = [S31, S32, S41, S42],
Square4 = [S33, S34, S43, S44],
valid([Row1, Row2, Row3, Row4,
Col1, Col2, Col3, Col4,
Square1, Square2, Square3, Square4]).
valid([]).
valid([Head | Tail]) :- fd_all_different(Head), valid(Tail).
| ?- sudoku([_, _, 2, 3,
_, _, _, _,
_, _, _, _,
3, 4, _, _],
Solution).
S = [4,1,2,3,2,3,4,1,1,2,3,4,3,4,1,2]
sudoku6(Puzzle, Solution) :-
Solution = Puzzle,
Puzzle = [S11, S12, S13, S14, S15, S16,
S21, S22, S23, S24, S25, S26,
S31, S32, S33, S34, S35, S36,
S41, S42, S43, S44, S45, S46,
S51, S52, S53, S54, S55, S56,
S61, S62, S63, S64, S65, S66],
fd_domain(Solution, 1, 6),
Row1 = [S11, S12, S13, S14, S15, S16],
Row2 = [S21, S22, S23, S24, S25, S26],
Row3 = [S31, S32, S33, S34, S35, S36],
Row4 = [S41, S42, S43, S44, S45, S46],
Row5 = [S51, S52, S53, S54, S55, S56],
Row6 = [S61, S62, S63, S64, S65, S66],
Col1 = [S11, S21, S31, S41, S51, S61],
Col2 = [S12, S22, S32, S42, S52, S62],
Col3 = [S13, S23, S33, S43, S53, S63],
Col4 = [S14, S24, S34, S44, S54, S64],
Col5 = [S15, S25, S35, S45, S55, S65],
Col6 = [S16, S26, S36, S46, S56, S66],
Square1 = [S11, S12, S13, S21, S22, S23],
Square2 = [S14, S15, S16, S24, S25, S26],
Square3 = [S31, S32, S33, S41, S42, S43],
Square4 = [S34, S35, S36, S44, S45, S46],
Square5 = [S51, S52, S53, S61, S62, S63],
Square6 = [S54, S55, S56, S64, S65, S66],
valid([Row1, Row2, Row3, Row4, Row5, Row6,
Col1, Col2, Col3, Col4, Col5, Col6,
Square1, Square2, Square3, Square4, Square5, Square6]),
pretty_print([Row1, Row2, Row3, Row4, Row5, Row6]).
valid([]).
valid([Head | Tail]) :- fd_all_different(Head), valid(Tail).
pretty_print([Head | Tail]) :-
print(Head),
print('\n'),
pretty_print(Tail).
| ?- sudoku6([1, _, _, _, _, _,
_, 5, _, 2, _, _,
_, 1, 6, _, 5, _,
_, 3, _, 6, 2, _,
_, _, 1, _, 3, _,
_, _, _, _, _, 5],
Solution).
[1,2,3,5,4,6]
[6,5,4,2,1,3]
[2,1,6,3,5,4]
[4,3,5,6,2,1]
[5,6,1,4,3,2]
[3,4,2,1,6,5]
| ?- sudoku([_, _, 2, 3,
_, _, _, _,
_, _, _, _,
3, 4, _, _],
Solution).
[4,1,2,3]
[2,3,4,1]
[1,2,3,4]
[3,4,1,2]
| ?- sudoku([5, 3, _, _, 7, _, _, _, _,
6, _, _, 1, 9, 5, _, _, _,
_, 9, 8, _, _, _, _, 6, _,
8, _, _, _, 6, _, _, _, 3,
4, _, _, 8, _, 3, _, _, 1,
7, _, _, _, 2, _, _, _, 6,
_, 6, _, _, _, _, 2, 8, _,
_, _, _, 4, 1, 9, _, _, 5,
_, _, _, _, 8, _, _, 7, 9],
Solution).
[5,3,4,6,7,8,9,1,2]
[6,7,2,1,9,5,3,4,8]
[1,9,8,3,4,2,5,6,7]
[8,5,9,7,6,1,4,2,3]
[4,2,6,8,5,3,7,9,1]
[7,1,3,9,2,4,8,5,6]
[9,6,1,5,3,7,2,8,4]
[2,8,7,4,1,9,6,3,5]
[3,4,5,2,8,6,1,7,9]
@brikis98
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment