我想知道如何在haskell中编写代码,以了解多次移动对于n个“光盘”和3个光圈(A,B,C)
基本情况(N = 1):运动A - > C所以1运动
感应情况(N = M + 1):我移动M盘“A”---> “C”和,我移动1张光盘“A”---> “B”,最后我将M盘从“C”移动到“B”。我认为de代码可能是这样的:
numMoveHanoi 0 = 0
numMoveHanoi 1 = 1
numMoveHanoi n = m+1 + numMoveHanoi m
where m = n-1
不幸的是,这仅适用于numMoveHanoi 2的情况。其他情况下,结果是错误的。我不知道我的递归定义在哪里错了。
谢谢大家。
答案 0 :(得分:5)
好吧,试着用你的Haskell排队英语。
numMoveHanoi {- Base case ( N=1) -} 1
= {- Movement A --> C so 1 movement -} 1
numMoveHanoi {- Inductive case -} n
= {- I move M discs "A" ---> "C" -} m
+ {- I move 1 disc "A" ---> "B" -} 1
+ {- I move M discs from "C" to "B" -} numMoveHanoi m
where {- ( N = M+1 ) -} m = n-1
现在,比较numMoveHanoi
的第一和第三个条款中的英语。然后比较numMoveHanoi
的第一和第三个子句中的Haskell。
(并且作为一个练习:比较第二和第三个条款中的英语。然后比较第二个和第三个条款中的Haskell。这是同一个bug的实例吗?为什么或为什么不呢?)
答案 1 :(得分:0)
考虑一下河内塔的递归解决方案:解决一个有n个光盘的塔,将顶部的n-1个光盘移到备用平台(numMoveHanoi(n-1)),移动第n个光盘(1),并将顶部的n-1个光盘移到第n个dics(numMoveHanoi(n-1))的顶部。那么你的一般情况:
numMovesHanoi n = numMoveHanoi (n-1) + 1 + numMoveHanoi (n-1)
{- or numMovesHanoi n = 2 * numMoveHanoi (n-1) + 1 -}