ふと思いたったので再帰呼び出ししてみる
…このタグつけるの何年ぶりだろう。…
なんてことはありません。いくつかの言語を使って、フィボナッチ数を求めるだけです。
1.Scheme
(define (fibo n) (define (fibo_inner n m k) (if (<= n 1) m (fibo_inner (- n 1) (+ m k) m))) (fibo_inner n 1 1)) (display (fibo 1000))(newline)
Cygwin上のguile(1.8.2)で実行した結果がこちら。
$ guile fibo.scm 7033036771142281582183525487718354977018126983635873274260490508715453711819693357974 2249494562611733487750449241765991088186363265450223647106012053374121273867339111198 139373125598767690091902245245323403501
Schemeは末尾最適化の実装を仕様で要求しているので、1000番目が10000番目でも計算できます。
あと、整数の大きさに制限がない(こちらの実装は「要求」ではなく、「奨励」らしい)ので、精確な値が見られます。(fibo 50000)とか、すごいことに。
function fibo(n) { function fibo_inner(n, m, k) { if (n <= 1) return m; else { return fibo.fibo_inner(n - 1, m + k, m); } } return fibo_inner(n, 1, 1); } System.inform(fibo(1000), "fibo!");
安定版(2.28 stable rev.3)を使った結果はこちら。
スクリプトで例外が発生しました EStackOverflow
エラーでした。再帰が深すぎて、スタックが溢れた?
ゲームの処理で、再帰を使うことなんてないから、大きな問題ではないのでしょう。
ちなみにエラーの回避法。
function fibo(n) { var m = 1, k = 1, t = 0; while (n > 1) { t = m; m = m + k; k = t; n--; } return m; }
末尾最適化を自分でやる(?)わけですな。
結果は、
9079565065540428013
Schemeと値が違うのは、桁あふれしたから?
3.Lua
なんとなく。
function fibo(n) function fibo_inner(n, m, l) if (n <= 0) then return m else return fibo_inner(n - 1, m + l, m) end end return fibo_inner(n, 1, 1) end print(fibo(1000))
$ lua fibo.lua 1.1379692539836e+209
…人生いろいろ?