sicpm1.27〜m1.33まで(4)
simpsonのところで手間取った。(バグ取り)
sicpはムチャ振りが少ないから、やってて楽しい。
今日したこと
;;復習。 (define (sum term a next b) (cond ((> a b) 0) (else (+ (term a) (sum term (next a) next b))))) (define (integral f a b dx) (define (add-dx x) (+ x dx)) (* (sum f (+ a (/ dx 2.0)) add-dx b) dx)) (define (cube x) (* x x x)) ;m1.29 ;;if文の対応の部分がおかしくなっていた。 ;;それを直すのに苦労した。 ;;(= i n)) の)がひとつたりなかった. (define (integral2 f a b n) (define (inc x) (+ x 1)) (define h (/ (- b a) n)) (define (y k) (f (+ a (* k h)))) (define (term i) (if (or (= i 0) (= i n)) (y i) (if (odd? i) (* 4 (y i)) (* 2 (y i))))) (* (sum term a inc n) (/ h 3.0))) ;;全部ぴったり1/4になった。 ;; gosh> (integral2 cube 0 1 100) ;; 0.25 ;; gosh> (integral2 cube 0 1 1000) ;; 0.25 ;; gosh> (integral cube 0 1 0.01) ;; 0.24998750000000042 ;; gosh> (integral cube 0 1 0.001) ;; 0.249999875000001 ;;==テスト用に使ったコード ;(define (f x) ; (define (g i) ; (if (or (= i 0) (= i x)) ;;こちらでは的確に動いていた。 ; (* 10 i) ; (if (odd? i) ; (* 100 i ) ; (* 1000 i))))) ; (sum g 0 inc x)) ;m1.30 ;;sumの反復版 ;;異様に簡単にできたので、確かめをする。 (define (sum2 term a next b) (define (iter a result) (if (> a b) result (iter (next a) (+ result (term a))))) (iter a 0)) ;;実験 ;; (define (square x) (* x x)) ;; (define (f x y) ;; (define (inc n) (+ n 1)) ;; (sum2 square x inc y)) ;; gosh> (f 0 10) ;; 385 ;; (確かめ) ruby -e 'p (0..10).inject(0) {|re,e|re+e**2}' #=>385 ;;合ってる。 ;m.1.31 (define (product term a b next) (define (iter result a) (if (> a b) result (iter (* result (term a)) (next a)))) (iter 1 a)) (define (inc x) (+ x 1)) (define (factorial n) (define (f x) x) (product f 1 n inc)) ;; gosh> (factorial 7) ;; 5040 ;4/πの計算 (define (square x) (* x x)) (define (pi/4 odd_number) (define (f a) (/ (square (inc a)) (square a))) (define (next n) (+ n 2)) (define (calc from) (/ (* 2.0 (product f from odd_number next)) (inc odd_number))) (calc 3)) ;; gosh> (pi/4 101) ;; 0.7892575441137919 ;; ruby -e 'p Math::PI/4' =>0.785398163397448 ;再帰的な方のproduct (define (product2 term a b next) (if (> a b) 1 (* (term a) (product2 term (next a) b next)))) ;;上のfactorialがproduct2を使うようにし変更して実行=>成功 ;m.1.32 ;<1>再帰的な方 (define (accumulate combiner null-value term a next b) (if (> a b) null-value (combiner (term a) (accumulate combiner null-value term (next a) next b)))) ;<2>反復的な方 (define (accumulate2 combiner null-value term a next b) (define (iter a result) (if (> a b) result (iter (next a) (combiner result (term a))) )) (iter a null-value)) ;;cube-sumの accumulate=> accumulate2で確認。成功。 ;;試しに何かを作ってみる。 (define (cube-sum a b) (accumulate + 0 cube a inc b)) ;; (cube-sum 1 3) => 36 ;;productだけ作ってみる (define (product3 term a b next) (accumulate * 1 term a b next b)) ;m1.33 (define (filltered-accumulate ok? combiner null-value term a next b) (define (iter a result) (cond ((> a b) result) ((ok? a) (iter (next a) (combiner result (term a)))) (else (iter (next a) result)))) (iter a null-value)) ;;a.を解く ;prime?を使えるようにする。 (define (prime? n) (define (smallest-divisor n) (find-divisor n 2)) (define (find-divisor n test-divisor) (cond ((> (square test-divisor) n) n) ((divides? test-divisor n) test-divisor) (else (find-divisor n (+ test-divisor 1))))) (define (divides? a b) (= (remainder b a) 0)) (= n (smallest-divisor n))) (define (square x) (* x x)) (define (a-to-b-prime-sum a b) (filltered-accumulate prime? + 0 square a inc b)) ;;これが作ったもの ;; gosh> (a-to-b-prime-sum 1 10) ;; 88 ;;=(+ 1 4 9 25 49) ;;bは省略。