sicpm1.14からm1.20まで

;m1.14
;;めんどそう。あとでする。

;;m.1.15
;; absは定義しなくても、もともと入ってた。
(define (cube x) (* x x x))
(define (p x ) (- (* 3 x) (* 4 (cube x))))
(define (sine angle)
  (if (not (> (abs angle) 0.1))
      angle
      (p (sine (/ angle 3.0)))))	   
;;(sine 12.15)
;;(p (sine (/ 12.15 3.0)))と増えていって、
;;最後はpが作用せずにangleが出力される。
;;ということでsineの回数-1=pの作用の回数。
(define (check x)
  (define (f  x count)
    (if (< (abs x) 0.1)
	count
	(f (/ x 3.0) (+ count 1))))
    (f x 0))
;;たぶん、これで表示されるものと同じ、それで5
;;ステップ数=2a (pとsineが実行される必要があるから、)
;;スペース ? (単語の意味を把握できてません><)

;;1.2.4
(define (expt b n)
  (if (= n 0) 
      1
      (* b (expt b (- n 1)))))
;;再帰
(define (expt2 b n)
  (define (expt-iter b counter product)
    (if (= counter 0)
	product
	(expt-iter b (- counter 1) product))))
;反復

(define (even? n)
  (= (remainder n 2) 0))
;;even?は既に用意されていた。
;;デフォルトで、remainderは用意されている?(教科書的に)
;;(exptもデフォルトで用意されている。)

;;m1.16
(define (expt3 b n)
  (define (expt-iter b counter product)
    (cond ((= counter 0) product)
	  ((even? counter)
	   (expt-iter (* b b) (/ counter 2) product))
	  (else
	   (expt-iter b (- counter 1) (* b product)))))
  (expt-iter b n 1))
;;プロセス logN

;;m1.17
(define (* a b)
  (if (= b 0)
      0
      (+ a (* a (- b 1)))))
;;n-> logNに変更
(define (double x) (* 2 x))
(define (halve x) (/ x 2))

(define (*_2 a b)
  (cond ((= b 0) 0)
	((even? b) (double (*_2 a (halve b))))
	(else (+ a (*_2 a (- b 1))))))	
;;再帰的

;;m1.18
(define (*_3 a b)
  (define (*_iter a b result)
    (cond ((= b 0) result)
	  ((even? b) (*_iter (double a) (halve b) result))
	  (else (*_iter a (- b 1) (+ result a)))))
  (*_iter a b 0))
;;反復的
    
;;m1.19
;;even?のときb->p a->qとする。
(define (fib n)
  (fib-iter 1 0 0 1 n))

(define (fib-iter a b p q count)
  (cond ((= count 0) b)
	((even? count)
	 (fib-iter a
		   b
		   (+ (* p p) (* q q))
		   (+ (* 2 p q) (* q q))
		   (/ count 2)))
	 (else (fib-iter (+ (* b q) (* a q) (* a p))
			 (+ (* b p) (* a q))
			 p
			 q
			 (- count 1)))))
;;できた。すごい時間かかった。
;;紙に書き始めて計算できなくなって…しばらく悩んだ。
   ;a<-bq+ap+aq, b=bp+aqより
   ;bp'+aq'=(bp+aq)p + (bq+ap+aq)q
   ;       =b(p*p + q*q) + a(qp+pq+q*q)
   ;       =b(p*p + q*q) + a(2pq+q*q)

;;1.2.5
;;remainder = %?
(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))
	  
;;m1.20
;とりあえず、実際に呼び出されたときに何回呼び出されるか数える。
(define (check a b count)
  (if (= b 0)
      count
      (check b (remainder a b) (+ count 1))))
;(check 206 40 0) ;=>4
;まじめに置き換えしてみる。その前に (define r remainder)
;;1。正規順序の時
(gcd 206 40)
(gcd 40 (r 206 40))
;	if +1
(gcd (r 206 40) (r 40 (r 206 40)))
;	if +2
(gcd (r 40 (r 206 40)) (r (r 206 40) (r 40 (r 206 40))))
;	if +4
(gcd (r (r 206 40) (r 40 (r 206 40))) (r (r 40 (r 206 40)) (r (r 206 40) (r 40 (r 206 40)))))
;	if +7(#t)
;;最後のaを計算 +4
;;count = 1 + 2 + 4 + 7 + 4 = 18

;;2,作用的順序のとき
(gcd 206 40)
(gcd 40 (r 206 40))
(gcd 40 6)
(gcd 6 (r 40 6)
(gcd 6 4)
(gcd 4 (r 6 4))
(gcd 4 2)
(gcd 2 (r 4 2))
(gcd 2 0)
2
;;count=4

今日はここまで