(wat-aro)

生きてます

SICP 問題 4.21

;; a
以下の式が階乗を計算すること確かめた後,フィボナッチ数を計算する手続きを作る.
((lambda (n)
  ((lambda (fact)
     (fact fact n))
   (lambda (ft k)
     (if (= k 1)
         1
         (* k (ft ft(- k 1)))))))
 10)
gosh> ((lambda (n)
        ((lambda (fact)
           (fact fact n))
         (lambda (ft k)
           (if (= k 1)
               1
               (* k (ft ft (- k 1)))))))
       10)
3628800
;; フィボナッチ数
((lambda (n)
   ((lambda (fact)
      (fact fact n))
    (lambda (ft k)
      (cond ((= k 0) 0)
            ((= k 1) 1)
            (else (+ (ft ft (- k 1))
                     (ft ft (- k 2))))))))
 10)

;; 確認用の手続き
(define (make-map-list n start proc)
  (map proc (iota n start 1)))
gosh> (make-map-list 10 1 (lambda (n)
                            ((lambda (fact)
                               (fact fact n))
                             (lambda (ft k)
                               (cond ((= k 0) 0)
                                     ((= k 1) 1)
                                     (else (+ (ft ft (- k 1))
                                              (ft ft (- k 2)))))))))
(1 1 2 3 5 8 13 21 34 55)
;; b
以下の式をaと同じように内部定義もletrecも使わずに定義する.
(define (f x)
  (define (even? n)
    (if (= n 0) true (odd? (- n 1))))
  (define (odd? n)
    (if (= n 0) false (even? (- n 1))))
  (even? x))

;; 答え
(define (f x)
  ((lambda (even? odd?)
     (even? even? odd? x))
   (lambda (ev? od? n)
     (if (= n 0) true (od? od? ev? (- n 1))))
   (lambda (od? ev? n)
     (if (= n 0) false (ev? ev? od? (- n 1))))))
gosh> (f 4)
#t
gosh> (f 5)
#f

問題文と引数の順序が違っていたので書き直し.

(define (f x)
  ((lambda (even? odd?)
     (even? even? odd? x))
   (lambda (ev? od? n)
     (if (= n 0) true (od? ev? od? (- n 1))))
   (lambda (ev? od? n)
     (if (= n 0) false (ev? ev? od? (- n 1))))))
gosh> (f 4)
#t
gosh> (f 5)
#f