SICP习题解答:第一章(下)
;; 1.29 (define (simpson-integral f a b n) (define (coefficient i) (cond ((or (= i 0) (= i n)) 1) ((even? i) 2) (else 4))) (let ((h (/ (- b a)n ))) (* (/ h 3) (sum (lambda (i) (* (f (+ a (* i h))) (coefficient i))) 0 (lambda (i) (+ i 1)) n)))) ;; 1.30 (define (sum term a next b) (define (iter a result) (if (> a b) result (iter (next a) (+ result (term a))))) (iter a 0)) ;; 1.31 只需要把sum改动两处。 ; 递归实现 (define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b)))) ; 迭代实现 (define (product term a next b) (define (iter a result) (if (> a b) result (iter (next a) (* result (term a))))) (iter a 1)) ; 阶乘 (define (factorial n) (product (lambda (x) x) 1 (lambda (i) (+ 1 i)) n)) ; π的近似值 (define (calc-pi n) (define (term i) (/ (- (square i) 1) (square i))) (define (next i) (+ 2 i)) (* 4 (product term 3.0 next n))) ;; 1.32 (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 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)) ;; 1.33 ; filtered-accumulate 的两种实现 (define (filtered-accumulate combiner null-value term a next b filter) (define (do-filter x) (if (filter x) x null-value)) (if (> a b) null-value (combiner (do-filter (term a)) (filtered-accumulate combiner null-value term (next a) next b filter)))) (define (filtered-accumulate combiner null-value term a next b filter) (define (do-filter x) (if (filter x) x null-value)) (define (iter a result) (if (> a b) result (iter (next a) (combiner result (do-filter (term a)))))) (iter a null-value)) ; (a) (filtered-accumulate + 0 (lambda (x) x) a (lambda (i) (+ 1 i)) b prime?) ; (b) (filtered-accumulate * 1 (lambda (x) x) 1 (lambda (i) (+ 1 i)) (- 1 n) (lambda (a) (= 1 (gcd a n)))) ;; 1.34 (f f)相当于(f 2),相当于(2 2),会因为2并非可以调用的函数而出错。 ;; 1.35 证明不动点直接计算即可,计算的(fixed-point (lambda (x) (+ 1 (/ 1 x))) 1.0)。 ;; 1.36 全部代码如下 (define tolerance 0.00001) (define (fixed-point f first-guess) (define (close-enough? v1 v2) (< (abs (- v1 v2)) tolerance)) (define (try guess) (display guess) (newline) (let ((next (f guess))) (if (close-enough? guess next) next (try next)))) (try first-guess)) (define (f x) (/ (log 1000) (log x))) (display (fixed-point f 2)) (newline) (newline) (display (fixed-point (lambda (x) (average x (f x))) 2)) (newline) (newline) ; 使用与不使用平均阻尼的步数分别为9与34步。 ;; 1.37 ; 递归版本 (define (cont-frac n d k) (define (shift f) (lambda (i) (f (+ 1 i)))) (if (= 0 k) 0 (/ (n 1) (+ (d 1) (cont-frac (shift n) (shift d) (- k 1)))))) ; 迭代版本 (dsefine (cont-frac n d k) (define (iter result i) (if (= 0 i) result (iter (/ (n i) (+ (d i) result)) (- i 1)))) (iter 0 k)) ; 当k不小于11时,结果有4位精度。 ;; 1.38 (define (e-2 k) (cont-frac (lambda (i) 1.0) (lambda (i) (if (= 2 (remainder i 3)) (* 2 (/ (+ 1 i) 3)) 1)) k)) ;; 1.39 (define (tan-cf x k) (cont-frac (lambda (i) (if (= 1 i) x (- (square x)))) (lambda (i) (- (* 2 i) 1)) k)) ;; 1.40 (define (cubic a b c) (lambda (x) (+ c (* x (+ b (* x (+ a x))))))) ;; 1.41 ; double函数 (define (double f) (lambda (x) (f (f x)))) ;; (((double (double double)) inc) 5) 的值为21。因为 (double double) 得到一个把参数过程应用四次的函数,而 (double (double double)) 事实上是将“把参数过程应用四次”的过程应用两次,也就是一个将参数过程应用十六次的函数。 ;; 1.42 (define (compose f g) (lambda (x) (f (g x)))) ;; 1.43 (define (repeated f n) (if (= 1 n) f (compose f (repeated f (- n 1))))) ;; 1.44 (define (n-times-smooth f dx n) ((repeated (lambda (f) (smooth f dx)) n) f)) ;; 1.45 (define (calc-nth-root-with-t-average-damps x n t) (fixed-point ((repeated average-damp t) (lambda (y) (/ x (fast-expt y (- n 1))))) 1.0)) ;; 通过实验,得到的规律是,当 2^t>=n 时,用 t 次平均阻尼求 n 次方根是可行的,于是有下面的程序。 (define (nth-root x n) (define (minimal-t n) (if (= 1 n) 0 (+ 1 (minimal-t (quotient n 2))))) (calc-nth-root-with-t-average-damps x n (minimal-t n))) ;; 1.46 (define (iterative-improve guess improve good-enough?) (if (good-enough? guess) guess (iterative-improve (improve guess) improve good-enough?))) (define (sqrt x) (define (improve y) (/ (+ x (square y)) (* 2 y))) (define (good-enough? y) (> tolerance (abs (- (square y) x)))) (iterative-improve 1.0 improve good-enough?)) (define (fixed-point f first-guess) (define (improve x) (f x)) (define (good-enough? x) (> tolerance (abs (- (f x) x)))) (iterative-improve first-guess improve good-enough?)) |


