上哈斯克爾研究一些「自我施加的功課」的一部分,我做了漢諾塔的經典解決方案:轉化漢諾塔運動順序爲配置順序
doHanoi :: Int -> Int -> Int -> [(Int, Int)]
doHanoi 0 _ _ = []
doHanoi n from to = first ++ [(from, to)] ++ last
where
using = 3 - from - to;
first = doHanoi (n - 1) from using;
last = doHanoi (n - 1) using to
(其中doHanoi n from to using
意義GET運動假設磁盤0.. n - 1
的asequence是在PEG from
,我們需要將它們移動到掛to
。)
這給運動的序列,例如
>>> doHanoi 3 0 2
[(0,2),(0,1),(2,1),(0,2),(1,0),(1,2),(0,2)]
然後我想看看是否可以將輸出轉換爲一組配置(即最初,所有環都位於左側掛鉤上,然後存在中間配置,最後所有環都位於右側掛鉤上)。然後我可以使用scanl
通過編寫changeConfig
功能
changeConfig :: [[Int]] -> (Int, Int) -> [[Int]]
changeConfig [e0:e0s, e1s, e2s] (0, 1) = [e0s, e0:e1s, e2s]
changeConfig [e0:e0s, e1s, e2s] (0, 2) = [e0s, e1s, e0:e2s]
changeConfig [e0s, e1:e1s, e2s] (1, 0) = [e1:e0s, e1s, e2s]
changeConfig [e0s, e1:e1s, e2s] (1, 2) = [e0s, e1s, e1:e2s]
changeConfig [e0s, e1s, e2:e2s] (2, 0) = [e2:e0s, e1s, e2s]
changeConfig [e0s, e1s, e2:e2s] (2, 1) = [e0s, e2:e1s, e2s]
做到這一點:
>>> scanl changeConfig [[0.. 2], [], []] (doHanoi 3 0 2 1)
[[[0,1,2],[],[]],[[1,2],[],[0]],[[2],[1],[0]],[[2],[0,1],[]],[[],[0,1],[2]],[[0],[1],[2]],[[0],[],[1,2]],[[],[],[0,1,2]]]
雖然這個作品,我覺得我失去了一些東西在changeConfig
:這是所有的配置只是一個窮舉,在具有某種形式的循環對稱性的環境中,碰巧發生了工作,因爲存在三個掛鉤,並且不能很好地伸縮(以LOC表示)。什麼是「Haskellic」的寫法?
發現能否請您記錄您的功能? 'n'究竟是什麼?究竟是「使用」?你在哪裏找到這個算法? – dfeuer
@dfeuer對不起,我添加了一個解釋。如果有其他問題,請LMK不清楚。謝謝! –
請注意,'using'不必被指定爲參數;它完全由'3 - (from + to)'指定。 – chepner