我正在尝试解决 Light-Up 难题,但在确定约束时遇到了麻烦。
我的主要谓词是:
akari(Rows, Size) :-
length(Rows, Size), maplist(length_list(Size), Rows),
append(Rows, Board),
domain(Board, 0, 2),
processRows(Rows, Rows, 0-0, Size),
% transpose(Rows, Columns),
% processRows(Columns, Columns, 0-0, Size),
labeling([], Board),
write(Board), nl,
printBoard(Board, Size).
它们是矩阵的Rows
形式,例如,每个自由正方形的情况:
start :-
akari([[_,_,_],
[_,_,_],
[_,_,_]], 3).
要处理我使用的每一行:
processRows([], _Board, _Row-_Col, _Size).
processRows([H|T], Board, Row-Col, Size) :-
processRow(H, Board, Row-Col, Size, []),
NewRow is Row + 1,
processRows(T, Board, NewRow-0, Size).
processRow([], _Board, _Row-_Col, _Size, _VarList).
processRow([H|T], _Board, _Row-Col, _Size, _VarList) :-
H == 2,
NewCol is Col + 1,
processRow(T, Board, Row-NewCol, Size, []).
processRow([H|T], Board, Row-Col, Size, VarList) :-
gatherLeft(Board, Row-Col, Row-Col, Size, VarList).
NewCol is Col + 1,
processRow(T, Board, Row-NewCol, Size, []).
所以我遍历矩阵的每个元素,然后我收集,从gatherLeft
- 它召唤其他基本集合,Right, Up 和 Down - 我正在处理的正方形的行和列。这个想法是,行和列的每个交叉点 - 如果你愿意,可以是一个十字 - 最多可以有一个灯泡。
但如果我做这样的事情:
count2([],0).
count2([H|T], Count) :-
H #= 1 #<=> C,
count2(T, C2),
Count #= C + C2.
或者这个 sum(VarList, #=<, 1)
我的意图是“每个十字架最多可以有一个灯泡”,但我最终选择了每个空间,最后我说“整个板最多可以有一个灯”。最后我得到一个空板。
编辑
对于后代,我想出的解决方案是:
每个方格最多可以有一个灯,所以sum([H], #=<, 1)
.
取一个正方形,它的列和行最多只能有一个灯,所以sum(Row, #=<, 1)
.
一个正方形的邻域必须至少有一个灯,所以sum(VarList, #>=, 1)
.
它现在似乎正在工作。