1

ライトアップ パズルを解こうとしていますが、制約を明確にするのに苦労しています。

私の主な述語は次のとおりです。

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

現在は機能しているようです。

4

0 に答える 0