私はSchemeを学んでおり、おもちゃの例として、Towers of Hanoiのソリューションベリファイア(ソルバーではない)を行っています。私は純粋に機能的なスタイルを使用したいと考えており (考え方を理解するためだけに)、タワーを 3 つのリストの単純なリストとして表しています。開始状態は次のようになります: '((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 であると想定しないでください。