我正在尝试解决河内难题,禁止移动。我有三个杆,一个左杆,一个中杆和一个右杆。在左杆上,我有两个盘子(最小的在顶部,最大的在底部),我想把它们放在右杆上。你可以一次只移动一个盘子。但这里有一个陷阱:你不能把一个大的盘子放在一个小的盘子上,然后把盘子从左极移到中极,再从中极移到右极。
我有以下算法:
type HanoiMovement = (Integer , Char , Char)
hanoi :: Integer -> [HanoiMovement]
hanoi n = hanoi_gen 'l' 'r' 'm' n
where
hanoi_gen s z aux 0 = []
hanoi_gen s z aux n = hanoi_gen s aux z (n-1) ++ [(n,s,z)] ++ hanoi_gen aux z s (n-1)
它会生成如何移动平板的解,但是它忽略了禁止的移动[('l ',' m '),('m','r')]。我如何将它们实现到算法中?
先谢谢你了
1条答案
按热度按时间mfpqipee1#
Well, your current solution to the "standard" Hanoi puzzle takes advantage of the fact that, say, moving 3 discs from left to right using middle (
hanoi 'l' 'r' 'm' 3
) can be recursively expressed as moving 2 discs from left to middle using right (hanoi 'l' 'm' 'r' 2
), then moving the'3'
disc from left to right, and then moving 2 discs from middle to right using left (hanoi 'm' 'r' 'l' 2
).In order to implement your modified Hanoi puzzle, you need to modify the recursion to take into account the forbidden moves. Because the forbidden moves break the symmetry of the poles, you won't be able to define a single recursive step that works for all values of
s
,z
, andaux
.Instead, you'll need to work through each of the cases:
To move
n
discs fromL
toR
without using the forbidden moves, you should moven-1
discs fromL
toM
, then move discn
fromL
toR
, and then moven-1
discs fromM
toR
, as usual. In other words:However, to move
n
discs fromL
toM
without using forbidden moves, you can't use the same pattern, as it would use the forbidden move(n,L,M)
, instead you need to first moven-1
discs fromL
toM
, then move discn
fromL
toR
, which is allowed, then moven-1
discs fromM
toL
, move discn
fromR
back toM
(also allowed), and finally moven-1
discs fromL
toM
. As code:If you define similar patterns for all permutations of the poles and use the usual base case. That should give you your solution.
SPOILERS FOLLOW....
.
.
.
.
The remaining patterns are:
If desired, these can be simplified somewhat with a helper, as follows, though it would be hard to see this pattern without writing them all out in detail first:
Full runnable example:
which gives solutions for 2 and 3 discs:
These appear to be correct.