フィボナッチ数の話
素数体係数多項式の拡張GCDを書かないといけないのだが, それはさておき.
ストリーム版が無いけど気にするな.
;;;素朴 (define (fib1 n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib1 (- n 1)) (fib1 (- n 2)))))) ;(time (fib1 30)) ; real 0.285 ; user 0.281 ; sys 0.000 ;;;末尾再帰 (define (fib2 n) (define (fib-iter i a b) (if (= n i) a (fib-iter (+ i 1) b (+ a b)))) (fib-iter 0 0 1)) ;(time (number? (fib2 100000))) ; real 1.407 ; user 1.217 ; sys 0.156 ;;;ハッシュ (define (fib3 n) (define fib-in-memo (let1 ht (make-hash-table 'eqv?) (define (memo m v) (hash-table-put! ht m v) v) (lambda (m) (cond ((= m 0) 0) ((= m 1) 1) ((hash-table-get ht m #f)) (else (memo m (+ (fib-in-memo (- m 1)) (fib-in-memo (- m 2))))))))) (fib-in-memo n)) ;(time (number? (fib3 100000))) ; real 2.077 ; user 1.514 ; sys 0.546 ;;;行列 ;;; (1 1) ;;; (f(n+2) f(n+1)) = (f(n+1) f(n)) (1 0) (use gauche.array) (define (fib4 n) (array-ref (array-expt (array (shape 0 2 0 2) 1 1 1 0) n) 1 0)) ;(time (number? (fib4 100000))) ; real 0.215 ; user 0.218 ; sys 0.000 ;;;エラー処理とか面倒ですよね (define (fib n) (if (and (integer? n) (not (negative? n))) (array-ref (array-expt (array (shape 0 2 0 2) 1 1 1 0) n) 1 0) (error "Non-negative integer required:" n)))