SICPの問題を解こう17
問題 1.31
product(積)版を書いてを計算せよという問題
(define (product term a next b) (if (> a b) 1 (* (term a) (exact->inexact (product term (next a) next b))))) (define (getpi n) (define (pi-term x) (if (even? x) (/ (+ x 2) (+ x 1)) (/ (+ x 1) (+ x 2)))) (define (pi-next x) (+ x 1)) (* 4 (product pi-term 1 pi-next n))) (print (getpi 10)) (print (getpi 100)) (print (getpi 1000)) (print (getpi 10000)) (print (getpi 100000)) (print (getpi 1000000))
結果
n | pi |
10 | 3.275101041334807 |
100 | 3.1570301764551645 |
1000 | 3.143160705532257 |
10000 | 3.1417497057379746 |
100000 | 3.1416083612780903 |
1000000 | 3.141594224382829 |
recursive process版
(define (product term a next b) (define (itr a result) (if (> a b) result (itr (next a) (exact->inexact (* (term a) result))))) (itr a 1)) (define (getpi n) (define (pi-term x) (if (even? x) (/ (+ x 2) (+ x 1)) (/ (+ x 1) (+ x 2)))) (define (pi-next x) (+ x 1)) (* 4 (product pi-term 1 pi-next n))) (print (getpi 10)) (print (getpi 100)) (print (getpi 1000)) (print (getpi 10000)) (print (getpi 100000)) (print (getpi 1000000))
有理数を小数にするのに exact->inexactを使用
問題 1.32
sumとproductはもっと抽象化出来、それをaccumulateとして実装せよという問題。
iterativeとrecursiveなprocessを両方書く
(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)))) (define (accumulate-recursive combiner null-value term a next b) (define (itr x result) (if (> a b) result (itr (next x) (combiner result (term x))))) (itr a null-value)) (define (term x) x) (define (next x) (+ x 1)) (define (sum n) (accumulate + 0 term 1 next n)) (define (product n) (accumulate * 1 term 1 next n)) (define (sum-recursive n) (accumulate + 0 term 1 next n)) (define (product-recursive n) (accumulate * 1 term 1 next n)) (print (sum 10)) (print (product 5)) (print (sum-recursive 10)) (print (product-recursive 5))
問題 1.33
accumulateの改良でfilter条件を満たすもののみaccumulateしていく
(define (filtered-accumulate filter combiner null-value term a next b) (cond ((> a b) null-value) ((filter a b) (combiner (term a) (filtered-accumulate filter combiner null-value term (next a) next b))) (else (combiner null-value (filtered-accumulate filter combiner null-value term (next a) next b))))) (define (gcd a b) (if (= b 0) a (gcd b (remainder a b)))) (define (relative-prime? a b) (= (gcd a b) 1)) (define (product-b n) (define (term x) x) (define (next x) (+ x 1)) (filtered-accumulate relative-prime? * 1 term 2 next n)) (display (product-b 5)) (newline)
問題 1.34
(define (f g) (g 2)) (f f)
interpreterが(f f)をどのようにevaluateするかという問題。
(f f) (f 2) (2 2)
となって「2」という定義がないという結論になると思う。
GuileのBacktrace
Backtrace: In unknown file: ?: 0* [primitive-load "1-34.sc"] In 1-34.sc: 4: 1* [display ... 4: 2* [f #] 2: 3 [f 2] 2: 4 [2 2] 1-34.sc:2:9: In expression (g 2): 1-34.sc:2:9: Wrong type to apply: 2
※GaucheでGuileのBacktraceのようなデバッグ情報吐き出すにはどうすればいいんだろう・・?
ないのかな?