Lispを試してみたかったのですが、すぐに諦めました。もう一度やってみようと思いました。私はプロジェクトオイラーの問題2を見ています-400万未満のすべてのフィボナッチ数の合計を見つけています。
私は動作する次のコードを書きましたが、あらゆる種類の醜いです。それらの中で最も重要なのは、それが非常に遅いという事実です-それは常に素朴な再帰を行っているからです。
このプログラムをPythonで作成したとき、数値を計算したときにリストを作成しましたが、数値を再計算することはありませんでした。私はここで(どういうわけか)それができることを知っていますが、それはLispの精神、関数型プログラミングには当てはまらないようです。再帰の深さの制限に達して、再帰の代わりにループを使用するようにコードを書き直さなければならなかったとき、私は#3の後で諦めました。
だから私の質問は次のとおりだと思います:
- この問題を解決するための「正しい、しなやかな方法」とは何ですか?
- 再帰と「すべてを計算するだけ」の概念を、すべてを計算する実際的な制限とどのように調和させますか?
- The LittleSchemerとProjectEuler以外にlispを学ぶための推奨事項はありますか?
そして、これが私のコードです:
(defun fib(i)
(if (= i 1) ;Could rewrite this as a case statement
1
(if (= i 2)
1
(+ (fib (- i 1)) (fib (- i 2))))))
(defun solve(i)
(let ((f (fib i))) ;Store result in local variable
(print f) ;For debugging
(if (< 4000000 f)
0 ;return
(if (= 0 (mod f 2))
(+ f (solve (+ i 1))) ;add number
(solve (+ i 1)))))) ;don't
(print (solve 1))