:- use_module(library(lists), [member/2]). :- use_module(contestlib, [map/3]). numbers(Numbers) :- findall(Number,number_in_grid(Number),Numbers). number_in_grid(Number) :- description(Number,Description), once(((lit(X,Y,_,_) ; lit(_,_,X,Y)), map(Description,rotate(_),RotatedDescription), matches(RotatedDescription,X,Y))). description(0,[up,up,right,down,down,left]). description(1,[down,down]). description(2,[right,down,left,down,right]). description(3,[right,down,left,right,down,left]). description(4,[down,right,up,down,down]). description(5,[left,down,right,down,left]). description(6,[down,down,right,up,left]). description(7,[right,down,down]). description(8,[up,right,down,down,left,up,right]). description(9,Description) :- description(6,Description). rotate( 0,X,X). rotate( 90,A,B) :- member((A,B),[(down,right),(right,up),(up,left),(left,down)]). rotate(180,A,B) :- rotate(90,A,C), rotate(90,C,B). rotate(270,A,B) :- rotate(90,B,A). matches([],_,_). matches([Step|Steps],X,Y) :- nextpoint(Step,X,Y,A,B), once((lit(X,Y,A,B) ; lit(A,B,X,Y))), matches(Steps,A,B). nextpoint( up, X,Y, A,B) :- A = X, B is Y + 1. nextpoint( down, X,Y, A,B) :- A = X, B is Y - 1. nextpoint(right, X,Y, A,B) :- A is X + 1, B = Y. nextpoint( left, X,Y, A,B) :- A is X - 1, B = Y.