3

数字が1〜8の3 * 3グリッドで、移動できる空白のスポット(0)があるパズルがあります。これがパズルの最終状態です。

1 2 3 
8 0 4 
7 6 5

この「状態」全体は、水平方向に読み取ることにより、state(1,2,3,8,0,4,7,6,5)で表されます。どのピースが適切な場所にあるかを確認する機能が必要です。

私は持っています:

h(state(A,B,C,D,E,F,G,H,I),Z) :-

これで、Zは正しい場所にあるピースの数になります。

A = 1
B = 2
C = 3
D = 8
E = 0
F = 4
G = 7
H = 6
I = 5

Zの出力を与える簡単な方法はありますか?どんな助けでもいただければ幸いです。ありがとう。

4

3 に答える 3

2

自分の情報をリストに保存できないのは確かですか?これは、従来の言語で、変数を反復処理する方法が必要な場合に、変数の束ではなく配列を使用する方法です。

于 2011-11-05T13:53:34.343 に答える
1

これをPrologで表現する簡単な方法がありますが、 CLP(FD)が必要です。

:- use_module(library(clpfd)).

h(State, Z) :-
    State =.. [state | Pos],
    maplist(equal, Pos, [0,1,2,3,8,0,4,7,6,5], Eq),
    sum(Eq, #=, Z).

equal(X, Y, E) :-
    E #<==> (X #= Y).
于 2011-11-05T11:55:31.930 に答える
0

これはかなり簡単なようです...

h(state(A,B,C,D,E,F,G,H,I),Z) :-
    count_matching([A,B,C,D,E,F,G,H,I], [1,2,3,8,0,4,7,6,5], 0, Z).

count_matching([], [], N, N).
count_matching([A|As], [B|Bs], N, M) :-
    (   A == B
    ->  T is N + 1
    ;   T is N
    ),
    count_matching(As, Bs, T, M).

SWI-Prolog集約ライブラリは、問題を解決するための別の簡単な方法を提供します。

:- [library(aggregate)].

h(state(A,B,C,D,E,F,G,H,I),Z) :-
    aggregate_all(count,
      (nth1(Index, [1,2,3,8,0,4,7,6,5], Cell),
       nth1(Index, [A,B,C,D,E,F,G,H,I], Cell)), Z).

Aggregate_allの使用はやり過ぎです。ここでは、同じスキーマを使用するより単純なプログラム(nth / 3を介した要素への非決定論的アクセス):

h(state(A,B,C,D,E,F,G,H,I),Z) :-
    findall(_,
      (nth1(Index, [1,2,3,8,0,4,7,6,5], Cell),
       nth1(Index, [A,B,C,D,E,F,G,H,I], Cell)), L),
    length(L, Z).
于 2011-11-05T15:50:19.227 に答える