プログラミング言語 Scheme 問題3.2.4

スマートな方法が思い浮かばないのは,今日も,腹筋プログラムをビリったから,
ということにします.
誰か助けてください.というか,ヒントください.
問題を要約すると,

フィボナッチ数を求めるプロシージャが2種類あります.
で,再帰呼び出しの回数を勘定するカウンタを,set! を使って作成し,
2種類のプロシージャを定義してください.

です.困っているのは,

  • fib1,fib2 を呼び出す前に,カウンタを初期化する必要があるので,初期化する必要がないようにしたい.内部的にやってほしい.
  • fib2 の方は,引数が3つあって,そのうち後ろの2つは決め打ちなんだから,引数を1つにしたい.

です.

  • 使える武器は,let, letrec, named-let, set! くらい?
(define fib1
  (lambda (n)
    (cond
     ((= n 0) 0)
     ((= n 1) 1)
     (else (+ (fib1 (- n 1)) (fib1 (- n 2)))))))

(define fib1-count 0)

(set! fib1
      (let ((old-fib1 fib1))
	(lambda (n)
	  (set! fib1-cnt (+ fib1-cnt 1))
	  (old-fib1 n))))

(define fib2
  (lambda (i a1 a2)
    (cond
     ((= i 0) 0)
     ((= i 1) a1)
     (else (fib2 (- i 1) (+ a1 a2) a1)))))

(define fib2-count 0)

(set! fib2
      (let ((old-fib2 fib2))
	(lambda (i a1 a2)
	  (set! fib2-count (+ fib2-count 1))
	  (old-fib2 i a1 a2))))

あっちをたてれば,こっちがたたん,みたいなかんじです.
あと,(fib1 35) とかやったら,カウンタが,29860703 とでて,びびっつ!!
fib2 なら,35回なのにね.おもしろですな.