我有一个3 * 3网格的拼图,其中有数字1-8,我可以移动一个空白点(0)。这是谜题的最终状态:
1 2 3
8 0 4
7 6 5
通过水平读取,整个“状态”由状态(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提供输出?任何帮助,将不胜感激。感谢。
答案 0 :(得分:2)
您确定无法将信息存储在列表中吗?如果您想要一种迭代它们的方法,那么在传统语言中如何使用数组而不仅仅是一堆变量。
答案 1 :(得分: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).
答案 2 :(得分: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).