End View Puzzle, Prolog

孤人 提交于 2019-12-11 09:58:50

问题


I'm trying to write a solver for End View Puzzles, using CLPFD (for those who are unfamiliar, here's a simple description http://www.funwithpuzzles.com/2009/12/abcd-end-view-a1.html ). I'm working on the constraint that I'll apply to each row/column, and running into some trouble.

So I'm thinking it should look something like this:

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

So the first 3 steps are pretty straight forward: initialize the board, set a domain, and make sure that this row won't repeat numbers other than 0 (I've written the stop_repeats/2 predicate). The problem I'm encountering is dealing with the left_value/3 predicate; I'm not really sure how to proceed here, since most of the list is not constrained and I do not actually know the position of this first positive element. Any help would be greatly appreciated!


回答1:


Maybe the automaton/3 constraint can help here? You can construct a finite automaton that accepts (optional) zero followed by the first letter as indicated, then an arbitrary sequence of zero and letters.




回答2:


I wrote down the puzzle specification. That seems less general than your description of it, then I hardcoded the constraints, using the mapping 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).

test:

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

I hope you can use it to solve your more general puzzle.



来源:https://stackoverflow.com/questions/10686773/end-view-puzzle-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!