ASP / Prolog / SAT 흐름 솔버 작성


9

Flow Free는 겹치지 않는 뱀을 통해 요소 쌍을 연결하고 전체 그리드를 채워야하는 중독성 안드로이드 게임입니다. 설명은 여기를 참조하십시오.

https://play.google.com/store/apps/details?id=com.bigduckgames.flow&hl=ko

나는 몇 가지 규칙에 불과한 ASP (응답 세트 프로그래밍) 솔루션을 가지고 있으며 SAT 인스턴스와 거의 동일하게 동일한 솔루션을 문구로 표현할 수는 없다고 생각하지만 잘못되었다는 것에 관심이 있습니다.

모든 언어는 괜찮지 만 일종의 솔버를 실행하지 않고 간결하게 수행 할 수 있는지 의심 스럽기 때문에 ASP / Prolog / SAT 레이블이 붙었습니다.

우승자는 가장 적은 문자입니다.

술어를 사용하여 문제점이 정의되었다고 가정 할 수 있습니다.

v(V). % A vertex

a(V,W). % V and W are adjacent

c(C). % A color

s(V,C). % V is an endpoint of color C

또한 입력이 만족

a(W,V) :- a(V,W) % Adjacencies are bidirectional

2{s(V,C) : v(V)}2 :- c(C). % Every color has exactly two endpoints

솔루션 술어는 다음과 같은 형식입니다.

e(V,W,C).

컬러 C의 V와 W 사이에 가장자리가 있다고 말합니다.

가장자리는 양방향이어야합니다 (같은 색상). 각 꼭짓점에는 정확히 한 가지 색의 가장자리가 있어야합니다. 끝점에는 정확히 하나의 모서리가 있고 다른 모든 정점에는 정확히 두 개의 모서리가 있습니다. 루프가 없으며 모든 뱀은 두 개의 끝점으로 추적 할 수 있어야합니다.

테스트 할 샘플 입력은 다음과 같습니다 (일반 팩의 5x5 레벨 2).

v(v11; v12; v13; v14; v15).
v(v21; v22; v23; v24; v25).
v(v31; v32; v33; v34; v35).
v(v41; v42; v43; v44; v45).
v(v51; v52; v53; v54; v55).

a(v11, v12).
a(v12, v13).
a(v13, v14).
a(v14, v15).
a(v12, v11).
a(v13, v12).
a(v14, v13).
a(v15, v14).
a(v11, v21).
a(v12, v22).
a(v13, v23).
a(v14, v24).
a(v15, v25).

a(v21, v22).
a(v22, v23).
a(v23, v24).
a(v24, v25).
a(v22, v21).
a(v23, v22).
a(v24, v23).
a(v25, v24).
a(v21, v31).
a(v22, v32).
a(v23, v33).
a(v24, v34).
a(v25, v35).
a(v21, v11).
a(v22, v12).
a(v23, v13).
a(v24, v14).
a(v25, v15).

a(v31, v32).
a(v32, v33).
a(v33, v34).
a(v34, v35).
a(v32, v31).
a(v33, v32).
a(v34, v33).
a(v35, v34).
a(v31, v41).
a(v32, v42).
a(v33, v43).
a(v34, v44).
a(v35, v45).
a(v31, v21).
a(v32, v22).
a(v33, v23).
a(v34, v24).
a(v35, v25).

a(v41, v42).
a(v42, v43).
a(v43, v44).
a(v44, v45).
a(v42, v41).
a(v43, v42).
a(v44, v43).
a(v45, v44).
a(v41, v51).
a(v42, v52).
a(v43, v53).
a(v44, v54).
a(v45, v55).
a(v41, v31).
a(v42, v32).
a(v43, v33).
a(v44, v34).
a(v45, v35).

a(v51, v52).
a(v52, v53).
a(v53, v54).
a(v54, v55).
a(v52, v51).
a(v53, v52).
a(v54, v53).
a(v55, v54).
a(v51, v41).
a(v52, v42).
a(v53, v43).
a(v54, v44).
a(v55, v45).

s(v11, yellow).
s(v45, yellow).
s(v41, blue).
s(v55, blue).
s(v51, red).
s(v43, red).
s(v42, green).
s(v33, green).

c(red; green; blue; yellow).

그리고 출력을 테스트하기 위해

shouldbe(v33,v32,green).
shouldbe(v42,v32,green).
shouldbe(v43,v53,red).
shouldbe(v51,v52,red).
shouldbe(v55,v54,blue).
shouldbe(v41,v31,blue).
shouldbe(v45,v35,yellow).
shouldbe(v11,v12,yellow).
shouldbe(v12,v11,yellow).
shouldbe(v35,v45,yellow).
shouldbe(v31,v41,blue).
shouldbe(v54,v55,blue).
shouldbe(v52,v51,red).
shouldbe(v53,v43,red).
shouldbe(v32,v42,green).
shouldbe(v32,v33,green).
shouldbe(v53,v52,red).
shouldbe(v52,v53,red).
shouldbe(v54,v44,blue).
shouldbe(v31,v21,blue).
shouldbe(v35,v25,yellow).
shouldbe(v12,v13,yellow).
shouldbe(v13,v12,yellow).
shouldbe(v25,v35,yellow).
shouldbe(v21,v31,blue).
shouldbe(v44,v54,blue).
shouldbe(v44,v34,blue).
shouldbe(v21,v22,blue).
shouldbe(v25,v15,yellow).
shouldbe(v13,v14,yellow).
shouldbe(v14,v13,yellow).
shouldbe(v15,v25,yellow).
shouldbe(v22,v21,blue).
shouldbe(v34,v44,blue).
shouldbe(v34,v24,blue).
shouldbe(v22,v23,blue).
shouldbe(v15,v14,yellow).
shouldbe(v14,v15,yellow).
shouldbe(v23,v22,blue).
shouldbe(v24,v34,blue).
shouldbe(v24,v23,blue).
shouldbe(v23,v24,blue).

:-not e(V,W,C),shouldbe(V,W,C).
:-e(V,W,C),not shouldbe(V,W,C).

또한 레벨 21 5x5는 하나 이상의 솔루션이있는 첫 번째 퍼즐이어야합니다 (특히 40이 아닌 9 개의 솔루션이 있습니다). 레벨 21을 설정하려면 입력의 마지막 몇 줄을

s(v55, yellow).
s(v44, yellow).
s(v15, blue).
s(v45, blue).
s(v51, red).
s(v53, red).
s(v22, green).
s(v14, green).
s(v23, orange).
s(v43, orange).

c(red; green; blue; yellow; orange).

답변:


4

ASP (클링 고), 180 바이트

{e(V,W,C):a(V,W),c(C)}.r(V):-s(V,_).r(V):-r(W),e(W,V,_).o(V):-r(V),{e(V,W,_):v(W);s(V,_)}=2.:-e(V,_,C),e(V,_,D),C!=D.:-e(V,W,C),not e(W,V,C).:-v(V),not o(V).:-s(V,C),e(V,_,D),C!=D.

ASP를 처음 사용하기 때문에이 작업이 다소 오래된 경우에도이 작업을 찾아서 기뻤습니다. 변형의 장소와 골프 기회가있어서 내 이해의 한계로 이어지는 것을 보는 것이 좋았습니다 (나는 여전히 옳기를 바랍니다.).

다음은 주석 처리 된 버전입니다.

% Select some edges e(V,W,C) s.t. V and W are adjacent and C is a color.
{e(V,W,C):a(V,W),c(C)}.

% Auxilary predicates:

% A vertex is reachable from an endpoint if
% it is an endpoint ...
r(V):-s(V,_).
% ... or it has an edge to it from a reachable vertex.
r(V):-r(W),e(W,V,_).

% A vertex is okay if it is reachable and either
% is an endpoint with one edge or is not an endpoint and has two edges.
% This is golfed to: the set of edges from V and endpoints V has
% cardinality 2.
o(V):-r(V),{e(V,W,_):v(W);s(V,_)}=2.

% Constraints:  We do not want ...

% edges from the same vertex with different colors:
:-e(V,_,C),e(V,_,D),C!=D.

% edges without their inverses:
:-e(V,W,C),not e(W,V,C).

% vertices that are not okay:
:-v(V),not o(V).

% edges from endpoints with the wrong color
:-s(V,C),e(V,_,D),C!=D.

% We're only interested in the e predicate:
#show e/3.

다른 ASP 솔버에 대해서는 모르겠지만 데비안의 gringo 패키지에 포함 된 clingo를 사용했습니다.

파일에 문제가 있고 파일 prob에 내 코드가 solve있으면를 호출하십시오 clingo 0 prob solve. 각 솔루션에 대해 사용하는 색상이 지정된 가장자리 목록과 #show줄 이없는 골프 버전을 사용하는 경우 다른 모든 술어가 표시됩니다 . 솔루션 수만 원하는 경우 옵션을 추가하십시오 -q. 솔루션이 하나 이상 있는지 만 알고 싶으면을없이 호출하십시오 0.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.