-1

Second End View Pazzles 7*7 (例http://www.funwithpuzzles.com/2009/10/abcd-second-end-view-ev4.htmlこの 5*5 のように)を解決するために swi-prolog でコードを記述します。数字 1 ~ 6

:- [library(clpfd)].

gen_row(Ls):-length(Ls, 7), Ls ins 0..6.

abc_view :-

maplist(gen_row, [R1,R2,R3,R4,R5,R6,R7]),
transpose([R1,R2,R3,R4,R5,R6,R7], [C1,C2,C3,C4,C5,C6,C7]),
maplist(all_distinct, [R1,R2,R3,R4,R5,R6,R7]),
maplist(all_distinct, [C1,C2,C3,C4,C5,C6,C7]),

start(R1, 4),
start(R2, 2),
start(R3, 3),
start(R4, 5),
start(R5, 3),
finish(R1, 6),
finish(R2, 4),
finish(R3, 2),
finish(R5, 1),
finish(R7, 2),

start(C2, 3),
start(C3, 4),
start(C4, 3),
start(C5, 5),
start(C6, 4),
start(C7, 1),
finish(C1, 3),
finish(C2, 2),
finish(C3, 5),
finish(C4, 5),
finish(C5, 6),
finish(C6, 1),
finish(C7, 4),

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

それを解決するためにどのようにロジックを書く必要があるか、おそらく4 * 4または5 * 5のより単純な例で..私はどんな助けにも満足しています. 私は3つのテストのためにそれを書く必要がありますが、それは1つでも問題ありません。

4

1 に答える 1

0

私は解決策を得ました。事実上、問題は以前に解決した「SkyScrape & Fences」パズルよりもはるかに単純です。

申し訳ありませんが、以前に問題を誤解し、間違ったコメントをして、既にたどった (正しい) パスを放棄するよう提案しました。

/*  File:    second_end_view_puzzle.pl
    Author:  Carlo,,,
    Created: Oct  8 2012
    Purpose: help to solve Second End View puzzle as quested at
             https://stackoverflow.com/q/12717609/874024
*/


:- [library(clpfd)].

gen_row(Ls) :-
    length(Ls, 7),
    Ls ins 0..6.

abc_view :-

    Rows = [R1,R2,R3,R4,R5,_R6,R7],
    maplist(gen_row, Rows),
    transpose(Rows, [C1,C2,C3,C4,C5,C6,C7]),
    maplist(all_distinct, Rows),
    maplist(all_distinct, [C1,C2,C3,C4,C5,C6,C7]),

    start(R1, 4),
    start(R2, 2),
    start(R3, 3),
    start(R4, 5),
    start(R5, 3),
    finish(R1, 6),
    finish(R2, 4),
    finish(R3, 2),
    finish(R5, 1),
    finish(R7, 2),

    start(C2, 3),
    start(C3, 4),
    start(C4, 3),
    start(C5, 5),
    start(C6, 4),
    start(C7, 1),
    finish(C1, 3),
    finish(C2, 2),
    finish(C3, 5),
    finish(C4, 5),
    finish(C5, 6),
    finish(C6, 1),
    finish(C7, 4),

    maplist(label, Rows),
    maplist(writeln, Rows).

% place the constraint 'SECOND in that direction' using a reified check
start(Vars, Num) :-
    Vars = [A,B,C|_],
    X #<==> ( A #= 0 #\/ B #= 0 ) #/\ C #= Num,
    Y #<==> A #\= 0 #/\ B #= Num,
    X + Y #= 1 .

finish(Vars, Num) :-
    reverse(Vars, Sarv), start(Sarv, Num).

編集テスト:

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

ここでの編集は、GnuProlog への「移植」です。SWI-Prolog CLP(FD) ライブラリから transpose/2 コードをコピーしました。

/*  File:    second_end_view_puzzle.pl
    Author:  Carlo,,,
    Created: Oct  8 2012
    Purpose: help to solve Second End View puzzle as quested at
             https://stackoverflow.com/q/12717609/874024
*/

gen_row(Ls) :-
    length(Ls, 7),
    fd_domain(Ls, 0, 6).

transpose(Ms, Ts) :-
        %must_be(list(list), Ms),
        (   Ms = [] -> Ts = []
        ;   Ms = [F|_],
            transpose(F, Ms, Ts)
        ).

transpose([], _, []).
transpose([_|Rs], Ms, [Ts|Tss]) :-
        lists_firsts_rests(Ms, Ts, Ms1),
        transpose(Rs, Ms1, Tss).

lists_firsts_rests([], [], []).
lists_firsts_rests([[F|Os]|Rest], [F|Fs], [Os|Oss]) :-
        lists_firsts_rests(Rest, Fs, Oss).

writeln(X) :- write(X), nl.

abc_view :-

    Rows = [R1,R2,R3,R4,R5,_R6,R7],
    maplist(gen_row, Rows),
    transpose(Rows, [C1,C2,C3,C4,C5,C6,C7]),
    maplist(fd_all_different, Rows),
    maplist(fd_all_different, [C1,C2,C3,C4,C5,C6,C7]),

    start(R1, 4),
    start(R2, 2),
    start(R3, 3),
    start(R4, 5),
    start(R5, 3),
    finish(R1, 6),
    finish(R2, 4),
    finish(R3, 2),
    finish(R5, 1),
    finish(R7, 2),

    start(C2, 3),
    start(C3, 4),
    start(C4, 3),
    start(C5, 5),
    start(C6, 4),
    start(C7, 1),
    finish(C1, 3),
    finish(C2, 2),
    finish(C3, 5),
    finish(C4, 5),
    finish(C5, 6),
    finish(C6, 1),
    finish(C7, 4),

    maplist(fd_labeling, Rows),
    maplist(writeln, Rows).

% place the constraint 'SECOND in that direction' using a reified check
start(Vars, Num) :-
    Vars = [A,B,C|_],
    X #<=> ( A #= 0 #\/ B #= 0 ) #/\ C #= Num,
    Y #<=> A #\= 0 #/\ B #= Num,
    X + Y #= 1 .

finish(Vars, Num) :-
    reverse(Vars, Sarv), start(Sarv, Num).
于 2012-10-08T08:40:45.253 に答える