Skip to content

Instantly share code, notes, and snippets.

@rdivyanshu
Last active July 3, 2023 13:35
Show Gist options
  • Save rdivyanshu/9918dc6ae47338122ee68701b937af74 to your computer and use it in GitHub Desktop.
Save rdivyanshu/9918dc6ae47338122ee68701b937af74 to your computer and use it in GitHub Desktop.
% number of rows and columns
#const r = 7.
#const c = 10.
% numbers(X, Y, N) is a relation when there is number N
% at coordinate (X, Y)
numbers(1, 3, 2; 1, 10, 4).
numbers(2, 4, 4; 2, 6, 2; 2, 8, 3).
numbers(3, 5, 3; 3, 7, 4).
numbers(4, 9, 5).
numbers(5, 3, 3; 5, 7, 2; 5, 10, 3).
numbers(6, 2, 2).
numbers(7, 6, 3; 7, 8, 3; 7, 9, 2).
% dots(X, Y) is relation when there is dot at coordinate (X, Y)
dots(1, 4). dots(1, 8). dots(2, 3).
dots(2, 5). dots(3, 4). dots(3, 6).
dots(4, 5). dots(5, 2). dots(5, 4).
dots(5, 5). dots(5, 6). dots(5, 9).
dots(6, 7).
% starts(I, D, O) is relation when numbers(X, Y, N) holds.
% It try to guess start of line passing through it. D is either
% N or W specifying whether line is vertical or horizontal.
% O is offset from number which can be at most N-1.
% Finally cardinality ( {..} = 1 ) specify select one of
% starting position. I is 0 based index of coordinates.
{ starts((X - 1) * c + Y, ("N"; "W"), (0..N-1)) } = 1 :- numbers(X, Y, N).
% span(I, LX, LY) is relation when line passing
% through X, Y (I = (X - 1) * c + Y) also passes
% through LX, LY. Defined using starts.
span((X - 1) * c + Y, X - O + (0..N-1), Y) :- starts((X - 1) * c + Y, "N", O), numbers(X, Y, N).
span((X - 1) * c + Y, X, Y - O + (0..N-1)) :- starts((X - 1) * c + Y, "W", O), numbers(X, Y, N).
% Integrity constraints
% No two different lines covers the same point
% Lines are identified using I (X, Y) from numbers(X, Y, N).
:- span(C1, X, Y), span(C2, X, Y), C1 != C2.
% Lines don't go outside box.
:- span(_, X, Y), X < 1.
:- span(_, X, Y), X > r.
:- span(_, X, Y), Y < 1.
:- span(_, X, Y), Y > c.
% If there is dot, there should be line passing through it.
:- dots(X, Y), not span(_, X, Y).
% Helper - from which coordinate drawing should begin and in which
% direction.
draw(X - O, Y, N, "S") :- starts((X - 1) * c + Y, "N", O), numbers(X, Y, N).
draw(X, Y - O, N, "E") :- starts((X - 1) * c + Y, "W", O), numbers(X, Y, N).
% show drawing instructions.
#show draw/4.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment