Towers of Hanoi
汉诺塔是一个数学问题:有A、B、C三根杆,A杆上有N(N>1)个穿孔圆盘,圆盘尺寸从下到上依次减小。目标是将A杆上的圆盘移动到C杆,圆盘尺寸仍然满足从下往上依次减小。移动的过程中需要遵守以下规则:
- 每次只能移动一个圆盘;
- 大盘不能叠在小盘上面。
解决该问题的思路是:想尽办法将圆盘从大到小依次放在C杆上,期间任何一杆都可以作为圆盘临时放置的杆。以N=3为例,
上图是初始状态,目标是要把A杆的圆盘整体搬移到C杆。所以,可以把问题分解成以下三步。
第一步:把A杆最上面的2(3-1=2)个圆盘移到B杆;
第二步:把A杆中最大的圆盘移到C杆;
第三步:此时B杆是要移动的杆,A杆是空闲的杆,同样的规则重复第一步,把B杆最上面的1(2-1=1)个圆盘移到A杆。
根据上面的描述,递归是一种很合适的方法。递归的第一步是要考虑一个最基础的情况(base case),也就是可以结束函数的条件。显然,对于上述问题,当圆盘数量n=1的时候,把圆盘从原来位置移动到目标位置便可以结束。递归的第二步要把问题分解成一个更加简单的问题。这里就是把n个圆盘的问题分解为n-1个圆盘的问题。
# python
def HanoiTowers(n, From, Spare, To):
if n == 1:
print('move', From, 'to', To)
else:
HanoiTowers(n-1, From, To, Spare)
print('move', From, 'to', To)
HanoiTowers(n-1, Spare, From, To)
// kotlin
fun HanoiTowers(n: Int, from: String, spare: String, to: String): Unit = when(n) {
1 -> println("move $from to $to")
else -> {
HanoiTowers(n-1, from, to, spare)
println("move $from to $to")
HanoiTowers(n-1, spare, from, to)
}
}