# sarabander/p2pu-sicp

1 parent 6904e83 commit c1ca637932f8a383c91f99ce32c5b2700641b9c9 committed Jul 5, 2011
Showing with 211 additions and 0 deletions.
1. +46 −0 1.3/Ex1.29.scm
2. +17 −0 1.3/Ex1.30.scm
3. +43 −0 1.3/Ex1.31.scm
4. +25 −0 1.3/Ex1.32.scm
5. +58 −0 1.3/Ex1.33.scm
6. +22 −0 1.3/Ex1.34.scm
 @@ -0,0 +1,46 @@ +;; Simpson’s Rule + +(define (square x) (* x x)) + +(define (cube x) (* x x x)) + +;; recursive sum +(define (sum term a next b) + (if (> a b) + 0 + (+ (term a) + (sum term (next a) next b)))) + +(define (simpson-integral f a b n) + (define (add-h x) (+ x h)) + (define h (/ (- b a) n)) + (define (summand x) + (define multiplier ; to make term multipliers like 1, 4, 2, 4, ... + (cond ((or (= x a) (= x b)) 1) + ((odd? (round (/ (- x a) h))) 4) ; if index k is odd + (else 2))) + (* multiplier (f x))) + (* (/ h 3) (sum summand a add-h b))) + +;; gives exact answers with integer arguments and even n: +(simpson-integral cube 0 1 100) ; 1/4 +(simpson-integral cube 0 1 134) ; 1/4 +(simpson-integral cube 0 1 1000) ; 1/4 + +;; odd n gives rational numbers, loses accuracy: +(simpson-integral cube 0 1 47) ; 1186417/4879681 is approx 0.24313413110406193 + +;; not very accurate with floating-point numbers and small n: +(simpson-integral cube 0 1 100.0) ; 0.24666666666666687 +(simpson-integral cube 0 1 1000.0) ; 0.24966666666666754 +(simpson-integral cube 0 1 10000.0) ; 0.2500333333332677 +(simpson-integral cube 0 1 100000.0) ; 0.2500033333324631 + +(simpson-integral cube 0 4 100) ; 64 + +(simpson-integral square 0 1 100) ; 1/3 +(simpson-integral square 0 3 100) ; 9 +(simpson-integral square 0 6 100) ; 72 +(simpson-integral square 0 9 100) ; 243 + +(simpson-integral square 0 1.1 100) ; 0.448
 @@ -0,0 +1,17 @@ +;; iterative sum +(define (sum term a next b) + (define (iter a result) + (if (> a b) + result + (iter (next a) (+ (term a) result)))) + (iter a 0)) + +(define (identity x) x) + +(define (inc x) (+ x 1)) + +(sum identity 1 inc 10) ; 55 +(sum cube 1 inc 10) ; 3025 + +(* 8 (pi-sum 1 1000)) ; 3.139592655589782 +(* 8 (pi-sum 1 100000000)) ; 3.1415926335405047
 @@ -0,0 +1,43 @@ +;; recursive product +(define (product term a next b) + (if (> a b) + 1 + (* (term a) + (product term (next a) next b)))) + +;; iterative product +(define (product term a next b) + (define (iter a result) + (if (> a b) + result + (iter (next a) (* (term a) result)))) + (iter a 1)) + +;; traditional definition of factorial +(define (factorial n) + (if (= n 0) + 1 + (* n (factorial (- n 1))))) + +;; new factorial using product +(define (factorial n) + (product identity 1 inc n)) + +(factorial 7) + +;; pi/4 formula after John Wallis +(define quarter-pi + (λ (max-factor) ; biggest factor in numerator (even) + (define add2 (λ (x) (+ x 2))) + (/ (* 2 + (product square 4 add2 (- max-factor 2)) + max-factor) + (product square 3 add2 (- max-factor 1))))) + +(define pi-approx + (λ (max-factor) + (* 4.0 (quarter-pi max-factor)))) + +(pi-approx 8)) ; 3.3436734693877552 +(pi-approx 100) ; 3.157339689217565 +(pi-approx 10000) ; 3.1417497371492673
 @@ -0,0 +1,25 @@ +;; recursive +(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)))) + +;; iterative +(define (accumulate combiner null-value term a next b) + (define (iter a result) + (if (> a b) + result + (iter (next a) (combiner (term a) result)))) + (iter a null-value)) + +(define (sum term a next b) + (accumulate + 0 term a next b)) + +(define (product term a next b) + (accumulate * 1 term a next b)) + +(sum identity 1 inc 10) ; 55 +(sum cube 1 inc 10) ; 3025 + +(factorial 7) ; 5040
 @@ -0,0 +1,58 @@ +;; Depends on 1.20, 1.21, 1.28 + +(define (filtered-accumulate filter + combiner + null-value + term + a + next + b) + (define (iter a result) + (if (> a b) + result + (iter (next a) + (combiner (if (filter a) + (term a) + null-value) + result)))) + (iter a null-value)) + +;; test +(+ (filtered-accumulate odd? + 0 identity 1 inc 10) + (filtered-accumulate even? + 0 identity 1 inc 10)) ; 55 + +(+ (filtered-accumulate odd? + 0 cube 1 inc 10) + (filtered-accumulate even? + 0 cube 1 inc 10)) ; 3025 + +(apply + (map cube '(1 2 3 4 5 6 7 8 9 10))) ; 3025 + +;; a. + +;; input are primes between 2 and 50 (result for reference point) +(apply + (map square '(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47))) ; 10466 + +;; with exhaustive prime test +(define (sum-prime-squares a b) + (filtered-accumulate prime? + 0 square a inc b)) + +;; with Miller-Rabin probabilistic test +(define (sum-prime-squares a b) + (filtered-accumulate miller-rabin-prime? + 0 square a inc b)) + +(sum-prime-squares 2 50) ; 10466 (matches the previous result) + +;; b. + +(define rel-prime? + (λ (n) + (λ (i) + (= (gcd i n) 1)))) + +((rel-prime? 20) 9) ; #t + +(define (prod-rel-prime n) + (filtered-accumulate (rel-prime? n) * 1 identity 1 inc (- n 1))) + +(prod-rel-prime 9) ; 2240 +(prod-rel-prime 10) ; 189 +(prod-rel-prime 11) ; 3628800
 @@ -0,0 +1,22 @@ +(define (f g) + (g 2)) + +;; Before evaluating (f f), I try to predict what happens: + +;; The inner scope of f obviously knows about outer environment where f is +;; defined. When supplied with f as an argument, the procedure f recursively +;; calls itself with argument 2. That in turn causes the 2 to be substituted +;; in place of g in (g 2), forming (2 2). Scheme tries to evaluate (2 2), but +;; throws an error, because 2 is not an operator. The sequence goes like this: + +;; (f f) +;; (f 2) +;; (2 2) +;; => error + +;; Let's test: + +(f f) ; => procedure application: expected procedure, given: 2; +; arguments were: 2 + +;; Prediction confirmed.