我试图为了好玩而做这个谜题:
http://qz.com/570665/can-you-solve-the-british-spy-agencys-ridiculously-difficult-christmas-puzzle/
我有1个黑色方块,0个白色方块。
我查询? - 解决(列表),追加(列表,Vars),标签(Vars),地图列表(writeln,Lists)。
我得到的答案与拼图的限制不符。
:-use_module(library(clpfd)).
%hopefully there are typos here! This has been copied by hand.
puzzle(RowLengths,ColLengths,BlackCoords):-
ColLengths =[
col(1, [7,2,1,1,7]),
col(2, [1,1,2,2,1,1]),
col(3, [1,3,1,3,1,3,1,3,1]),
col(4, [1,3,1,1,5,1,3,1]),
col(5, [1,3,1,1,4,1,3,1]),
col(6, [1,1,1,2,1,1]),
col(7, [7,1,1,1,1,1,7]),
col(8, [1,1,3]),
col(9, [2,1,2,1,8,2,1]),
col(10,[2,2,1,2,1,1,1,2]),
col(11,[1,7,3,2,1]),
col(12,[1,2,3,1,1,1,1]),
col(13,[4,1,1,2,6]),
col(14,[3,1,1,1,3,1]),
col(15,[1,2,5,2,2]),
col(16,[2,2,1,1,1,1,2,1]),
col(17,[1,3,3,2,1,8,1]),
col(18,[6,2,1]),
col(19,[7,1,4,1,1,3]),
col(20,[1,1,1,1,4]),
col(21,[1,3,1,3,7,1]),
col(22,[1,3,1,1,1,2,1,1,4]),
col(23,[1,3,1,4,3,3]),
col(24,[1,1,2,2,2,6,1]),
col(25,[7,1,3,2,1,1])
],
RowLengths=[
row(1, [7,3,1,1,7]),
row(2, [1,1,2,2,1,1]),
row(3, [1,3,1,3,1,1,3,1]),
row(4, [1,3,1,1,6,1,3,1]),
row(5, [1,3,1,5,2,1,3,1]),
row(6, [1,1,2,1,1]),
row(7, [7,1,1,1,1,1,7]),
row(8, [3,3]),
row(9, [1,2,3,1,1,3,1,1,2]),
row(10,[1,1,3,2,1,1]),
row(11,[4,1,4,2,1,2]),
row(12,[1,1,1,1,1,4,1,3]),
row(13,[2,1,1,1,2,5]),
row(14,[3,2,2,6,3,1]),
row(15,[1,9,1,1,2,1]),
row(16,[2,1,2,2,3,1]),
row(17,[3,1,1,1,1,5,1]),
row(18,[1,2,2,5]),
row(19,[7,1,2,1,1,1,3]),
row(20,[1,1,2,1,2,2,1]),
row(21,[1,3,1,4,5,1]),
row(22,[1,3,1,3,10,2]),
row(23,[1,3,1,1,6,6]),
row(24,[1,1,2,1,1,2]),
row(25,[7,2,1,2,5])
],
BlackCoords= [
[4,4],[5,4], [13,4],[14,4],[22,4],
[7,9],[8,9],[11,9],[15,9],[16,9],[19,9],
[7,17],[12,17],[17,17],[21,17],
[4,22],[5,22],[10,22],[11,22],[16,22],[21,22],[22,22]
].
%This is meant to set each index value from blacks in list to one
list_of_blacks(List,Blacks):-
length(Blacks,NumberOfBlacks),
length(NumberOfOnesList,NumberOfBlacks),
NumberOfOnesList ins 1..1,
maplist(my_nth1(List),Blacks,NumberOfOnesList).
%This is meant to take a row or column and set the values to one, which are needed to meet the constraint for that row or col
row(List,LengthsOfBlacks):-
maplist(my_length,LengthsOfBlacks,BlackLists),
splitlistIf(=(1),List,BlackLists).
x_cords(Xs):-
puzzle(_,_,BlackCords),
length(BlackCords,Len),
length(Xs,Len),
maplist(nth1(1),BlackCords,Xs).
y_cords(Ys):-
puzzle(_,_,BlackCords),
length(BlackCords,Len),
length(Ys,Len),
maplist(nth1(2),BlackCords,Ys).
solve(Puzzle):-
generate_matrix(25,25,Puzzle),
flatten(Puzzle,Flat),
Flat ins 0..1,
x_cords(XCords),
y_cords(YCords),
maplist(my_set(Puzzle),XCords,YCords),
puzzle(RowLengths,ColLengths,_),
maplist(remove_row,RowLengths,RowBlacks),
maplist(remove_col,ColLengths,ColBlacks),
maplist(row,Puzzle,RowBlacks),
transpose(Puzzle,PuzzleT),
maplist(row,PuzzleT,ColBlacks).
%%%%%%%%%%%%%%%helpers
my_nth1(List,Index,El):-
nth1(Index,List,El).
my_length(Len,List):-
length(List,Len).
generate_matrix(Cols, Rows, Matrix) :-
my_length(Rows, Matrix),
maplist(my_length(Cols), Matrix).
remove_row(X,Y):-
X=row(_,Y).
remove_col(X,Y):-
X=col(_,Y).
my_set(M,Row,Col) :-
nth1(Row,M,RowList),
nth1(Col,RowList,1).
%%%Other preds from stack overflow
if_(If_1, Then_0, Else_0) :-
call(If_1, T),
( T == true -> call(Then_0)
; T == false -> call(Else_0)
; nonvar(T) -> throw(error(type_error(boolean,T),_))
; /* var(T) */ throw(error(instantiation_error,_))
).
=(X, Y, T) :-
( X == Y -> T = true
; X \= Y -> T = false
; T = true, X = Y
; T = false,
dif(X, Y) % ISO extension
% throw(error(instantiation_error,_)) % ISO strict
).
equal_t(X, Y, T) :-
=(X, Y, T).
split_if(P_2,As,Bss) :- splitlistIf(P_2,As,Bss).
splitlistIf(P_2,As,Bss) :-
list_pred_split(As,P_2,Bss).
list_pred_split([],_,[]).
list_pred_split([X|Xs],P_2,Bss) :-
if_(call(P_2,X), list_pred_split(Xs,P_2,Bss),
(Bss = [[X|Ys]|Bss0], list_pred_open_split(Xs,P_2,Ys,Bss0))).
list_pred_open_split([],_,[],[]).
list_pred_open_split([X|Xs],P_2,Ys,Bss) :-
if_(call(P_2,X), (Ys = [], list_pred_split(Xs,P_2,Bss)),
(Ys = [X|Ys0], list_pred_open_split(Xs,P_2,Ys0,Bss))).