GCHQ拼图,有什么不对?

时间:2015-12-11 15:08:54

标签: prolog puzzle clpfd

我试图为了好玩而做这个谜题:

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))).

0 个答案:

没有答案