4

每个人都知道著名的河内序言

你可以在这里找到

它很棒但是当我写这个查询时移动(3,左,右,中心)。

它没有显示这些结果

Move top disk from left to right
Move top disk from left to center
Move top disk from right to center 
Move top disk from left to right 
Move top disk from center to left 
Move top disk from center to right 
Move top disk from left to right 

我得到的是

Trace: >> RETURN: nl()
Trace: >> RETURN: hanoi(1,left,right,center)
Trace: >> RETURN: hanoi(2,center,right,left)
Trace: >> RETURN: hanoi(3,left,right,center)
True
1 Solution

那么我怎样才能让它以更好的方式打印结果,并且是否可以命名磁盘,以便程序将它们命名给我,以显示结果如下“从左到右移动磁盘 A”

对不起,如果我问了很多,但上帝我喜欢 PROLOG。

4

2 回答 2

3

首先,您使用什么 Prolog 来获得这些结果?看起来您启用了调试器或其他东西。我强烈推荐SWI-Prolog,它给出了正确的结果。

至于命名光盘,是的,你可以做到。考虑这样的事情:

move([Disc],X,Y,_) :-  
    write('Move disk '),
    write(Disc),
    write(' from '), 
    write(X), 
    write(' to '), 
    write(Y), 
    nl. 
move([Bottom|Rest],Start,Swap,Goal) :- 
    move(Rest,Start,Swap,Goal), 
    move([Bottom],Start,Goal,_), 
    move(Rest,Swap,Goal,Start).

当你运行时,move([biggest,middle,smallest], left, center, right).你会得到这样的结果:

Move disk smallest from left to center
Move disk middle from left to right
Move disk smallest from center to right
Move disk biggest from left to right
Move disk smallest from center to right
Move disk middle from center to left
Move disk smallest from right to left

这里的诀窍是这是一个自下而上的算法。从本质上讲,它归结为:

  1. 将底部磁盘顶部的所有内容移动到交换(这是递归步骤)
  2. 将底部圆盘移动到目标
  3. 将其他所有内容从交换移至目标

因为它是自下而上的,所以您必须给出从最底部的光盘开始的列表。

于 2009-04-13T20:11:03.470 回答
0

我想编辑要经过同行评审需要很长时间,所以我会在这里发布更正。Pesto 发布的代码有一个错误。正确的版本(带有更漂亮的输出格式)如下所示:

move([Disc],X,_,Y) :-  
    format("Move disk ~w from ~w to ~w\n", [Disc, X, Y]).
move([Bottom|Rest],Start,Swap,Goal) :- 
    move(Rest,Start,Goal,Swap), 
    move([Bottom],Start,_,Goal),
    move(Rest,Swap,Start,Goal).

在 GNU Prolog 下检查。

于 2012-02-04T17:23:08.383 回答