changeset 67:8906b5a4517f

Calculate and validate boxes The solver now creates answers for valid sudoku, but doesn't reject invalid ones (e.g. dupe in column)
author IBBoard <dev@ibboard.co.uk>
date Sat, 07 Oct 2017 15:07:34 +0100
parents 2acc1ad8d365
children b4f994693f7b
files 3-Prolog/day3-sudoku.pl
diffstat 1 files changed, 29 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/3-Prolog/day3-sudoku.pl	Mon Oct 02 21:02:22 2017 +0100
+++ b/3-Prolog/day3-sudoku.pl	Sat Oct 07 15:07:34 2017 +0100
@@ -12,12 +12,14 @@
     board(X, Y, Board),
     rows(Board, Max, Rows),
     cols(Board, Max, Cols),
+    boxes(Board, X, Y, Boxes),
     valid(Rows),
-    valid(Cols).
-% TODO: Calculate boxes and validate them
+    valid(Cols),
+    valid(Boxes).
 
 board(X, Y, Board) :-
-    Size is X * Y * X * Y,
+    % Y * X boxes of size X * Y
+    Size is (Y * X) * (X * Y),
     board(Size, Board).
 board(1, [_]).
 board(Size, [_|Board]) :- SmallerSize is Size - 1, board(SmallerSize, Board).
@@ -43,4 +45,27 @@
 cols(Board, ColLength, ColNum, [NewCol|Cols]) :- ColNum =< ColLength, NextColNum is ColNum + 1,
     nth_from_list(ColNum, ColLength, Board, NewCol),
     cols(Board, ColLength, NextColNum, Cols).
-cols(_, ColLength, ColNum, []) :- ColNum > ColLength.
\ No newline at end of file
+cols(_, ColLength, ColNum, []) :- ColNum > ColLength.
+
+in_box(BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY) :-
+    PosX >= BoxX * MaxBoxWidth, PosX < (BoxX + 1) * MaxBoxWidth,
+    PosY >= BoxY * MaxBoxHeight, PosY < (BoxY + 1) * MaxBoxHeight.
+
+box(_, _, _, MaxBoxWidth, MaxBoxHeight, _, PosY, []) :- PosY >= MaxBoxWidth * MaxBoxHeight.
+box([Head|Tail], BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY, [Head|Box]) :-
+    in_box(BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY),
+    PosX < (MaxBoxWidth * MaxBoxHeight) - 1, NextX is PosX + 1,
+    box(Tail, BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, NextX, PosY, Box).
+box([Head|Tail], BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY, [Head|Box]) :-
+    in_box(BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY), 
+    PosX >= (MaxBoxWidth * MaxBoxHeight) - 1, NextX is 0, NextY is PosY + 1,
+    box(Tail, BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, NextX, NextY, Box).
+box([_|Tail], BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY, Box) :- 
+    \+ in_box(BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY), PosX < (MaxBoxWidth * MaxBoxHeight) - 1, NextX is PosX + 1, box(Tail, BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, NextX, PosY, Box).
+box([_|Tail], BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY, Box) :- 
+    \+ in_box(BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, PosX, PosY), PosX >= (MaxBoxWidth * MaxBoxHeight) - 1, NextX is 0, NextY is PosY + 1, box(Tail, BoxX, BoxY, MaxBoxWidth, MaxBoxHeight, NextX, NextY, Box).
+
+boxes(Board, BoxWidth, BoxHeight, Boxes) :- boxes(Board, BoxWidth, BoxHeight, 0, 0, Boxes).
+boxes(_, MaxBoxY, MaxBoxX, BoxX, BoxY, []) :- BoxY >= MaxBoxY.
+boxes(Board, MaxBoxY, MaxBoxX, BoxX, BoxY, [Box|Boxes]) :- BoxX < (MaxBoxX - 1), BoxY < MaxBoxY, box(Board, BoxX, BoxY, MaxBoxY, MaxBoxX, 0, 0, Box), NextX is BoxX + 1,  boxes(Board, MaxBoxY, MaxBoxX, NextX, BoxY, Boxes).
+boxes(Board, MaxBoxY, MaxBoxX, BoxX, BoxY, [Box|Boxes]) :- BoxX >= (MaxBoxX - 1), BoxY < MaxBoxY, box(Board, BoxX, BoxY, MaxBoxY, MaxBoxX, 0, 0, Box), NextY is BoxY + 1, boxes(Board, MaxBoxY, MaxBoxX, 0, NextY, Boxes).
\ No newline at end of file