Prolog 河内序言塔
您好,我对河内塔的实施有问题。 我需要打印带有必要移动的列表,但我的算法仅在光盘数量为N=1时有效。 这是我的密码Prolog 河内序言塔,prolog,towers-of-hanoi,dcg,Prolog,Towers Of Hanoi,Dcg,您好,我对河内塔的实施有问题。 我需要打印带有必要移动的列表,但我的算法仅在光盘数量为N=1时有效。 这是我的密码 move(1,X,Y,_,L) :- append([X],[Y],L). move(N,X,Y,Z) :- N>1, M is N-1, move(M,X,Z,Y), move(1,X,Y,_), move(M,Z,Y,X). 这是N=1时的结果 ?- move(1,left,right,_,L). L = [
move(1,X,Y,_,L) :-
append([X],[Y],L).
move(N,X,Y,Z) :-
N>1,
M is N-1,
move(M,X,Z,Y),
move(1,X,Y,_),
move(M,Z,Y,X).
这是N=1时的结果
?- move(1,left,right,_,L).
L = [left,right]
(16 ms) yes
我需要这样的东西
L = [[left,center],[left,right],[center,right],[left,center],[right,left],
[right,center],[left,center],[left,right],[center,right],[center,left],
[right,left],[center,right],[left,center],[left,right],[center,right]]
当N=4时
如果有人能帮助我,我将不胜感激。您可以写一些小改动:
move(1,X,Y,_,[[X,Y]]).
move(N,X,Y,Z,L) :-
N>1,
M is N-1,
move(M,X,Z,Y,L1),
move(1,X,Y,_,L2),
move(M,Z,Y,X,L3),
append(L1,L2,L4),
append(L4,L3,L).
例如:
?- move(4,left,right,center,L).
L = [[left, center], [left, right], [center, right], [left, center], [right, left], [right, center], [left, center], [left, right], [center, right], [center, left], [right, left], [center, right], [left, center], [left, right], [center, right]] ;
false.
在Prolog中描述<强>列表<强>时,始终考虑使用<强> <强>符号> 例如,考虑:
moves(1, X, Y, _) --> [X-Y]. moves(N, X, Y, Z) --> { N #> 1, M #= N-1 }, moves(M, X, Z, Y), moves(1, X, Y, _), moves(M, Z, Y, X).如果这是与此处所示完全相同的代码,请注意
move
的第一个子句有5个参数,而第二个子句只有4个参数。我几乎可以肯定这是一个错误。很高兴这有帮助!!真棒的回答,注意结果是列表而不是列表,但这样更清楚…谢谢你的鼓励!是的,我已经冒昧地改用成对的。要使用列表列表,只需更改第一条规则,将X-Y
替换为[X,Y]
,这是术语。(X),(Y,[])
,因此与-(X,Y)
相比有些浪费。
?- phrase(moves(4,left,right,center), Ls).
Ls = [left-center, left-right, center-right, left-center, right-left, ... ].