在河内的prolog塔上实现计数器
我有一个程序在早上使用Prolog 我正在实施河内塔 我需要的帮助是每次打印在河内的prolog塔上实现计数器,prolog,counter,towers-of-hanoi,Prolog,Counter,Towers Of Hanoi,我有一个程序在早上使用Prolog 我正在实施河内塔 我需要的帮助是每次打印将光盘编号从uu移动到。我需要增加一个计数器,说Move X:“String”String是移动内容的前一个语句 在程序结束时,我需要打印完成拼图所需的移动总数。目前,我的程序是自下而上递归设置的。一个常见问题是将IO与计算混为一谈。最好是通过一个包装器谓词和一个随结果实例化的参数来隔离IO 考虑这一点(代码旨在演示计数器的添加,而不是解决问题): 即使上面的代码与您拥有的代码无关,同样的过程也适用:添加参数以传输计数器
将光盘编号从uu移动到
。我需要增加一个计数器,说Move X:“String”
String是移动内容的前一个语句
在程序结束时,我需要打印完成拼图所需的移动总数。目前,我的程序是自下而上递归设置的。一个常见问题是将IO与计算混为一谈。最好是通过一个包装器谓词和一个随结果实例化的参数来隔离IO 考虑这一点(代码旨在演示计数器的添加,而不是解决问题): 即使上面的代码与您拥有的代码无关,同样的过程也适用:添加参数以传输计数器,并使用递归对其进行递增
或者,也有但通常不受欢迎的方法,因为它们很容易被误用和编写过程程序。与其编写一个do-all谓词,不如将其分解为do-one-thing谓词:
[1->2,3->1,…]
)length/2
谓词已经允许您计算列表中的移动次数使用此变量,可以调用
hanoi(3,左,中,右,Moves NMoves)
,移动列表将实例化为移动
,移动次数将实例化为NMoves
。可以很容易地编写谓词,将每个列表成员格式化为输入/输出
注意这里如何使用差异列表来避免昂贵的append/3
。hanoi/5
谓词中的length/2
调用可以证明生成的移动列表大小正确
hanoi(N, Src, Aux, Dest, Moves-NMoves) :-
NMoves is 2^N - 1,
length(Moves, NMoves),
move(N, Src, Aux, Dest, Moves-_).
move(1, Src, _, Dest, [Src->Dest|Rest]-Rest) :- !.
move(2, Src, Aux, Dest, [Src->Aux,Src->Dest,Aux->Dest|Rest]-Rest) :- !.
move(N, Src, Aux, Dest, Moves-Rest) :-
N0 is N-1,
move(N0, Src, Dest, Aux, Moves-M1),
move(1, Src, Aux, Dest, M1-M2),
move(N0, Aux, Src, Dest, M2-Rest).
更具可读性的方法可能涉及使用DCG隐藏管道:
hanoi(N, Src, Aux, Dest, Moves-NMoves) :-
NMoves is 2^N - 1,
length(Moves, NMoves),
phrase(move(N, Src, Aux, Dest), Moves).
move(1, Src, _, Dest) --> !,
[Src->Dest].
move(2, Src, Aux, Dest) --> !,
[Src->Aux,Src->Dest,Aux->Dest].
move(N, Src, Aux, Dest) -->
{ succ(N0, N) },
move(N0, Src, Dest, Aux),
move(1, Src, Aux, Dest),
move(N0, Aux, Src, Dest).
最好是显示一些代码。如果没有看到代码的相关部分,很难有任何上下文来回答。对不起,伙计们,我会记得下次发布代码。谢谢你的帮助!format/2对于组合连续的写入/1调用也很有用,例如:format(“使用~w磁盘所需的步骤数为~w.”,[N,Count])。使用DCG来描述列表将使其更具可读性。@mat,这是可能的。我添加了你的建议作为替代方法。
hanoi(N, Src, Aux, Dest, Moves-NMoves) :-
NMoves is 2^N - 1,
length(Moves, NMoves),
phrase(move(N, Src, Aux, Dest), Moves).
move(1, Src, _, Dest) --> !,
[Src->Dest].
move(2, Src, Aux, Dest) --> !,
[Src->Aux,Src->Dest,Aux->Dest].
move(N, Src, Aux, Dest) -->
{ succ(N0, N) },
move(N0, Src, Dest, Aux),
move(1, Src, Aux, Dest),
move(N0, Aux, Src, Dest).