ライトアップ パズルを解こうとしていますが、制約を明確にするのに苦労しています。
私の主な述語は次のとおりです。
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
調べて、処理中の四角形の行と列の右、上、下のカーディナル ギャザーを呼び出します。アイデアは、行と列の各交点 - 必要に応じてクロス - は、最大で 1 つの電球を持つことができるということです。
しかし、私がこのようなことをすると:
count2([],0).
count2([H|T], Count) :-
H #= 1 #<=> C,
count2(T, C2),
Count #= C + C2.
または、この sum(VarList, #=<, 1)
私の意図は「各クロスには最大で 1 つの電球を付けることができる」ということですが、最終的にはすべてのスペースを選択してしまい、「ボード全体に最大で 1 つのライトを付けることができます」と言ってしまいます。そして、空のボードになってしまいます。
編集
後世のために、私が思いついた解決策は次のとおりです。
すべての正方形は、最大 1 つのライトを持つことができるので、sum([H], #=<, 1)
.
正方形を取ると、その列と行は最大で 1 つのライトを持つことができるので、sum(Row, #=<, 1)
.
正方形の近傍には少なくとも 1 つのライトが必要なので、sum(VarList, #>=, 1)
.
現在は機能しているようです。