0

我正在尝试使用 CLPFD 为 End View Puzzles 编写求解器(对于那些不熟悉的人,这里有一个简单的描述http://www.funwithpuzzles.com/2009/12/abcd-end-view-a1.html) . 我正在研究将应用于每一行/列的约束,并遇到了一些麻烦。

所以我认为它应该看起来像这样:

% NxN board, numbers from 0 to M in the row, Left/Right are the clues
% corresponding to the row
endviews(N,M,List,Left,Right):- 
    length(List,M),
    domain(List,0,M),
    stop_repeats(List,M),
    left_value(List,M,Left),
    reverse(List,RList),
    left_value(RList,M,Right)
    .

所以前三个步骤非常简单:初始化板,设置域,并确保该行不会重复除0(我已经写了stop_repeats/2谓词)以外的数字。我遇到的问题是处理left_value/3谓词;我不太确定如何在这里进行,因为列表中的大部分内容都不受限制,而且我实际上并不知道第一个积极元素的位置。任何帮助将不胜感激!

4

2 回答 2

2

也许automaton/3约束可以在这里提供帮助?您可以构造一个有限自动机,它接受(可选)零,后跟所示的第一个字母,然后是任意的零和字母序列。

于 2012-05-21T15:40:46.807 回答
1

我写下了拼图规范。这似乎不如您对它的描述一般,然后我使用映射 0=empty,1=A,2=B,3=C 对约束进行了硬编码。

/*  File:    abc_view.pl
    Author:  Carlo,,,
    Created: May 21 2012
    Purpose:
*/

:- module(abc_view, [abc_view/0]).
:- [library(clpfd), '~/prolog/lambda'].

abc_view :-
    maplist(\Ls^(length(Ls, 4), Ls ins 0..3), [R1,R2,R3,R4]),
    transpose([R1,R2,R3,R4], [C1,C2,C3,C4]),

    maplist(all_distinct, [R1,R2,R3,R4]),
    maplist(all_distinct, [C1,C2,C3,C4]),

    start(R2, 3),
    start(R3, 3),
    finish(R3, 2),

    start(C3, 1),
    finish(C2, 2),

    maplist(writeln, [R1,R2,R3,R4]).

finish(X, V) :-
    reverse(X, Y),
    start(Y, V).

start([0,Y|_], Y).
start([Y|_], Y).

测试:

?- abc_view.
[2,0,1,3]
[0,3,2,1]
[3,1,0,2]
[1,2,3,0]
true ;
false.

我希望你能用它来解决你更普遍的难题。

于 2012-05-21T18:29:42.323 回答