我正在學習Scheme,並且作爲一個玩具的例子,我正在爲河內的Towers做解決方案驗證者(而不是求解器)。 我想使用純粹的功能風格(只是爲了進入思維),我代表塔作爲三個列表的簡單列表。起始狀態可能如下所示: '((0 1 2 3 4)()())在河內的塔樓移動光盤的習慣性功能方式
我該如何實現一個函數,該函數需要一個狀態,一個源索引和一個目標索引,並返回新的州?在命令式的風格,這將是像一些小事:
state[target].push(state[source].pop())
但我能想到的每一個功能的解決方案是非常令人費解。例如:
(define (makeMove state source target)
(letrec ((recMake (lambda(tower pos disc)
(if (null? tower) '()
(cons (if (eqv? pos source)
(cdr (car tower))
(if (eqv? pos target)
(cons disc (car tower))
(car tower)))
(recMake (cdr tower)
(+ pos 1)
disc))))))
(recMake state 0 (car (list-ref state source)))))
這似乎工作,但必須有更好的方法。我想地圖會比遞歸好一些,但仍然太多。如果我以不同的方式表示狀態,會更容易嗎?
此外,隨時批評我的代碼。我真的不知道我在做什麼。
編輯: 如果可能的話,我寧願你不要以爲塔的數量總是3.
謝謝!不過,我希望有更簡單的事情。看起來你讓我的解決方案更簡單一些,因爲它不那麼一般(硬編碼塔的數量)。我會編輯這個問題,使其更清楚,我更喜歡普遍性。這些數字是光盤的大小,所以更大的數字不能放在較小的數字上。 – Gurgeh
就像我剛纔提到的那樣,表達這一點的普通函數方式是將硬編碼爲每個塔的東西變成一個考慮索引的map。我會立即編輯我的答案,向你展示我的意思。 – mquander
(哦,當然這就是數字,Duh。) – mquander