Головоломка "Ханойские башни" (пролог) - PullRequest
4 голосов
/ 13 апреля 2009

каждый знает знаменитый пролог Ханой

и вы можете найти его ЗДЕСЬ

и это здорово, но когда я пишу этот запрос, переместите (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.

Ответы [ 2 ]

3 голосов
/ 14 апреля 2009

Прежде всего, какой пролог вы используете, чтобы получить эти результаты? Похоже, у вас включен отладчик или что-то. Я настоятельно рекомендую 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. Переместить все остальное от свопа к цели

Поскольку это снизу вверх, вы должны указать список, начиная с самого нижнего диска.

0 голосов
/ 04 февраля 2012

Полагаю, что исправления рецензируются вечно, поэтому я просто опубликую здесь исправление. Код, опубликованный Песто, содержит ошибку. Правильная версия (с более красивым форматированием вывода) выглядит так:

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.

...