SICP解答メモ&解説 (問題1.11〜問題1.13)
問題1.11
とりあえず再帰プロセスの手続きを書いてみよう。
(define (f n) (if (< n 3) n (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))))
これは定義式をそのまま書くだけので楽。で、実行結果はこうなった。
gosh> (f 3)
CALL f 3
----------f(n - 1) ----------
CALL f 2
RETN f 2
----------f(n - 2)----------
CALL f 1
RETN f 1
----------f(n - 3)----------
CALL f 0
RETN f 0
RETN f 4
4
今度はn=4の時
ふむ、確かに木構造再帰しているみたいですね。
gosh> (f 4)
CALL f 4
----------レベル1のf(n - 1)------------
CALL f 3
----------レベル2のf(n - 1)---------
CALL f 2
RETN f 2
----------レベル2のf(n - 2)---------
CALL f 1
RETN f 1
----------レベル2のf(n - 3)---------
CALL f 0
RETN f 0
RETN f 4
----------レベル1のf(n - 2)-------------
CALL f 2
RETN f 2
----------レベル1のf(n - 3)-------------
CALL f 1
RETN f 1
RETN f 11
11
では次に反復プロセスを書いてみよう。反復プロセスは状態変数(state variable)を書いて末尾再帰的にすればよいから…
ってあれ書けない…う〜ん、フィボナッチ数の時の反復プロセスの求め方は、載ってたのをそのまま書いただけなんだよな。で、その求め方の例として両替の話があって…ってそこから反復プロセス求めてないじゃん。
ここから関数型言語の勉強にSICPを読もう - (7) 1章 - 反復をマスターしたいけど・・・ - higepon blogを参考にしつつ進めてみる。もう一回フィボナッチ数を反復プロセスで求めた手続きを見みる。
; this process is linear iterative. ; state variable (define (fib-imp n) (fib-iter 1 0 n)) (define (fib-iter a b count) (if (= count 0) b (fib-iter (+ a b) a (- count 1))))
これはフィボナッチ数の「fib(0) = 0, fib(1) = 1」で値を初期化して、「計算を積み上げていっている感じ」である。
とりあえず書いてみた。
; iterative (define (f n) (define iter 1st 2nd 3rd count) (cond ((= count 0) 1st) ((= count 1) 2nd) ((= count 2) 3rd) (else (iter ))) (iter 0 1 2 n))
これは「n < 3」の時のはっきりとわかっている時の値を初期化した。しかし、どう「計算を積み上げるか」がお手上げ状態になってしまって書けなかった。
解答集の解答は、
(define (f-iter n) (define (iter a b c count) (cond ((= count 0) c) ((= count 1) b) (else (iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))) (iter 2 1 0 n))
う〜む…
で、反復プロセス練習!!練習!!練習!! - どらや記で練習してもう一回やってみた結果…
(define (f n) (f-iter 2 1 0 n)) (define (f-iter a b c count) (cond ((= count 2) a) ((= count 1) b) ((= count 0) c) (else (f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1)))))
う〜む…微妙に解答集と違う…ぐぬぬ
問題1.12
何を解けばいいのかいまいちわからないのでパス。
問題1.13
フィボナッチ数の証明問題なのでパス。