#lang sicp (define (square x) (* x x)) (define (sum-of-square x y) (+ (square x) (square y))) (define (abs x) (if (> x 0) x (- x))) (define (>= x y) (not (< x y))) (define (ex-1-3 a b c) (cond ((and (< a b) (< a c)) (sum-of-square b c)) ((and (< b a) (< b c)) (sum-of-square a c)) (else (sum-of-square a b)))) (define (good-enough? guess x) (< (abs (* (- guess x) 1000)) x)) (define (average x y) (/ (+ x y) 2)) (define (sqrt x) (define (sqrt-improve guess x) (average guess (/ x guess))) (define (sqrt-iter guess x) (if (good-enough? (square guess) x) guess (sqrt-iter (sqrt-improve guess x) x))) (sqrt-iter 1.0 x)) (define (cube x) (* x x x)) (define (cbrt x) ; Exercise 1.8 (define (cbrt-iter guess x) (if (good-enough? (cube guess) x) guess (cbrt-iter (/ (+ (/ x (square guess)) (* 2 guess)) 3) x))) (cbrt-iter 1.0 x)) (define (dec x) (- x 1)) (define (inc x) (+ x 1)) (define (factorial n) (if (= n 1) 1 (* n (factorial (dec n))))) ; Exercise 1.10 (define (A x y) (cond ((= y 0) 0) ((= x 0) (* 2 y)) ((= y 1) 2) (else (A (dec x) (A x (dec y)))))) (define (f n) (A 0 n)) ; return 2n (define (g n) (A 1 n)) ; return n logical-and 2^n (define (h n) (A 2 n)) ; return n logical-and (2 up-arrow up-arrow 2) (define (fibonacci n) (define (fibonacci-iter a b m) (if (= m n) b (fibonacci-iter b (+ a b) (inc m)))) (if (= n 0) 0 (fibonacci-iter 0 1 1))) (define (count-change amount) (define (first-denomination kinds-of-coins) (cond ((= kinds-of-coins 1) 1) ((= kinds-of-coins 2) 5) ((= kinds-of-coins 3) 10) ((= kinds-of-coins 4) 25) ((= kinds-of-coins 5) 50))) (define (cc amount kinds-of-coins) (cond ((= amount 0) 1) ; this means the coin change is valid ((or (< amount 0) (= kinds-of-coins 0)) 0) (else (+ (cc amount (dec kinds-of-coins)) (cc (- amount (first-denomination kinds-of-coins)) kinds-of-coins))))) (cc amount 5)) ; Exercise 1.11 (define (f-recursive n) (if (< n 3) n (+ (f-recursive (dec n)) (* (f-recursive (- n 2)) 2) (* (f-recursive (- n 3)) 3)))) (define (f-iterative n) (define (f-iter a b c count) (if (= count 0) c (f-iter b c (+ c (* b 2) (* a 3)) (dec count)))) (if (< n 3) n (f-iter 1 2 4 (- n 3)))) ; Exercise 1.12 (define (combination-pascal n r) (if (or (= n 1) (= r 1)) 1 (+ (combination-pascal (dec n) (dec r)) (combination-pascal (dec n) r)))) (define (combination n r) ; well, factorial is recursive :-) (/ (factorial n) (factorial r) (factorial (- n r)))) (define (even? n) (= (remainder n 2) 0)) (define (expt-recursive b n) (cond ((= n 0) 1) ((even? n) (square (expt-recursive b (/ n 2)))) (else (* (expt-recursive b (dec n)) b)))) ; Exercise 1.16 (define (expt-iterative b n) (define (expt-iter b n a) (cond ((= n 0) a) ((even? n) (expt-iter (square b) (/ n 2) a)) (else (expt-iter b (dec n) (* a b))))) (expt-iter b n 1)) ; Exercise 1.17 (define (double n) (+ n n)) (define (halve n) (/ n 2)) (define (mul-recursive a b) (cond ((= b 0) 0) ((< b 0) (mul-recursive (- a) (- b))) ; halve only works on even intergers, thus even? must also be included ((even? b) (double (mul-recursive a (halve b)))) (else (+ (mul-recursive a (dec b)) a)))) ; Exercise 1.18 (define (mul-iterative a b) (define (mul-iter a b c) (cond ((= b 0) c) ((even? b) (mul-iter (double a) (halve b) c)) (else (mul-iter a (dec b) (+ c a))))) (if (< b 0) (mul-iter (- a) (- b) 0) (mul-iter a b 0))) (define (fib n) (define (fib-iter a b p q count) ; Tpq(a, b) = (bq + aq + ap, bp + aq) ; Tpq(Tpq(a, b)) = (..., (bp + aq)p + (bq + aq + ap)q) ; = (..., b(pp + qq) + a(2pq + qq)) ; => p' = pp + qq, q' = 2pq + qq (cond ((= count 0) b) ((even? count) (fib-iter a b (sum-of-square p q) (+ (* 2 p q) (square q)) (/ count 2))) (else (fib-iter (+ (* b q) (* a q) (* a p)) (+ (* b p) (* a q)) p q (dec count))))) (fib-iter 1 0 0 1 n)) ; Exercise 1.23 (define (smallest-divisor n) (define (find-divisor test-divisor) (cond ((> (square test-divisor) n) n) ((= (remainder n test-divisor) 0) test-divisor) (else (find-divisor (+ test-divisor 2))))) (if (even? n) 2 (find-divisor 3))) (define (prime? n) (and (> n 1) (= (smallest-divisor n) n))) (define (expmod x y z) (cond ((= y 0) 1) ((even? y) (remainder (square (expmod x (/ y 2) z)) z)) (else (remainder (* (expmod x (dec y) z) x) z)))) (define (fermat-prime-trial n a) (= (expmod a n n) a)) (define (fermat-prime? n times) (define (fermat-test n) (fermat-prime-trial (inc (random (dec n))))) (cond ((= times 0) true) ((fermat-test n) (fermat-prime? n (dec times))) (else false))) ; Exercise 1.22 (define (timed-prime-test n) (define (report-prime elapsed-time) (display " *** ") (display elapsed-time)) (define (start-prime-test n start-time) (if (prime? n) (report-prime (- (runtime) start-time)) false)) (newline) (display n) (start-prime-test n (runtime))) (define (search-for-primes start n) (cond ((< n 0)) ; wow this is valid ((even? start) (search-for-primes (inc start) n)) ((timed-prime-test start) (search-for-primes (+ start 2) (dec n))) (else (search-for-primes (+ start 2) n)))) ; Exercise 1.25 (define (expmod-lousy x y z) (remainder (expt-recursive x y) z)) (define (expmod-effeciency-test func x y z) (define (display-elapsed start-time) (func x y z) (display (- (runtime) start-time)) (newline)) (display-elapsed (runtime))) ; Exercise 1.27 (define (slow-fermat-prime? n) (define (slow-iter count) (cond ((= count 1) true) ((fermat-prime-trial n count) (slow-iter (dec count))) (else false))) (slow-iter (dec n))) ; Exercise 1.28 (define (miller-rabin n) (define (nontrivial-sqrt-1-mod? m) (let ((r (remainder (square m) n))) (if (or (not (= r 1)) (= m 1) (= m (dec n))) r 0))) (define (expmod-1 x y) (cond ((= y 0) 1) ((odd? y) (remainder (* (expmod-1 x (dec y)) x) n)) (else (nontrivial-sqrt-1-mod? (expmod-1 x (/ y 2)))))) (define (miller-rabin-trail a) (= (expmod-1 a (dec n)) 1)) (define (miller-rabin-iter count) (cond ((= count 0)) ((miller-rabin-trail (inc (random (dec n)))) (miller-rabin-iter (dec count))) (else false))) (cond ((= n 2) true) ((or (< n 2) (even? n)) false) (else (miller-rabin-iter (/ (dec n) 2))))) (define (sum term a next b) (if (> a b) 0 (+ (term a) (sum term (next a) next b)))) (define (identity x) x) (define (sum-integers a b) (sum identity a inc b)) (define (sum-cubes a b) (sum cube a inc b)) (define (pi-sum a b) (sum (lambda (x) (/ 1.0 x (+ x 2))) a (lambda (x) (+ x 4)) b)) (define dx 0.00001) (define (integral f a b dx) (* (sum f (+ a (/ dx 2.0)) (lambda (x) (+ x dx)) b) dx)) ; Exercise 1.29 (define (simpson-integral f a b n) (define h (/ (- b a) n)) ; sorry! (define (fk k) (f (+ a (* k h)))) (define (y k) (cond ((= (remainder k n) 0) (fk k)) ((even? k) (* (fk k) 2)) (else (* (fk k) 4)))) (define (simpson-iter k) (if (= k 0) (y 0) (+ (y k) (simpson-iter (dec k))))) (* (simpson-iter n) h 1/3)) ; Exercise 1.30 (define (sum-iter term a next b) (define (iter a result) (if (> a b) result (iter (next a) (+ (term a) result)))) (iter a 0)) ; Exercise 1.31 (define (product-recursive term a next b) (if (> a b) 1 (* (term a) (product-recursive term (next a) next b)))) (define (pi-fourth precision) (define (john-wallis-term n) (* (if (even? n) (/ n (inc n)) (/ (inc n) n)) 1.0)) (product-recursive john-wallis-term 2 inc (+ (* (abs precision) 2) 2))) (define (product-iterative term a next b) (define (iter a result) (if (> a b) result (iter (next a) (* (term a) result)))) (iter a 1)) ; Exercise 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 (sum-recursive term a next b) (accumulate + 0 term a next b)) (define (accumulate-iter 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)) ; Exercise 1.33 (define (filtered-accumulate filter combiner null-value term a next b) (if (> a b) null-value (combiner (if (filter a) (term a) null-value) (filtered-accumulate filter combiner null-value term (next a) next b)))) (define (sum-square-primes a b) (filtered-accumulate prime? + 0 square a inc b)) (define (product-relative-primes n) (filtered-accumulate (lambda (i) (= (gcd i n) 1)) * 1 identity 1 inc (dec n))) (define (search f neg-point pos-point) (let ((midpoint (average neg-point pos-point))) (if (good-enough? neg-point pos-point) midpoint (let ((test-value (f midpoint))) (cond ((positive? test-value) (search f neg-point midpoint)) ((negative? test-value) (search f midpoint pos-point)) (else midpoint)))))) (define (half-interval-method f a b) (let ((a-value (f a)) (b-value (f b))) (cond ((and (negative? a-value) (positive? b-value)) (search f a b)) ((and (negative? b-value) (positive? a-value)) (search f b a)) (else (error "Values are not of opposite sign" a b))))) (define (fixed-point f first-guess) (define (try guess) (let ((next (f guess))) (if (good-enough? guess next) next (try next)))) (try first-guess)) (define (sqrt-fixed x) (fixed-point (lambda (y) (average y (/ x y))) 1.0)) ; Exercise 1.35 (define golden-ratio (fixed-point (lambda (x) (inc (/ x))) 1.0)) ; Exercise 1.37 (define (cont-frac-recursive n d k) (define (cont-frac n d k root) (if (= k 0) root (cont-frac n d (dec k) (/ (n k) (+ (d k) root))))) (if (> k 0) (cont-frac n d (dec k) (/ (n k) (d k))) (error "You weirdo!"))) (define (cont-frac-iterative n d k) (define (cont-frac n d k c) (if (< c k) (/ (n c) (+ (d c) (cont-frac n d k (inc c)))) (/ (n k) (d k)))) ; UB if k is not a positive integer (cont-frac n d k 1)) ; Exercise 1.38 (define (e-2 precision) (cont-frac-iterative (lambda (i) 1.0) (lambda (i) (if (= (remainder i 3) 2) (* (inc i) 2/3) 1.0)) precision)) ; Exercise 1.39 (define (tan-cf x k) (cont-frac-iterative (lambda (i) (if (= i 1) x (square x))) (lambda (i) ((if (even? i) - +) (dec (* i 2)))) k)) (define (average-damp f) (lambda (x) (average x (f x)))) (define (newton-method g guess) (define (deriv g) (lambda (x) (/ (- (g (+ x dx)) (g x)) dx))) (let ((f (lambda (x) (- x (/ (g x) ((deriv g) x)))))) (fixed-point f guess))) (define (fixed-point-of-transform g transform guess) (fixed-point (transform g) guess)) ; Exercise 1.40 (define (cubic a b c) (lambda (x) (+ (cube x) (* (square x) a) (* x b) c))) ; Exercise 1.41 (define (duplicate f) (lambda (x) (f (f x)))) ; Exercise 1.42 (define (compose f g) (lambda (x) (f (g x)))) ; Exercise 1.43 (define (repeated f times) (cond ((< times 1) identity) ((= times 1) f) (else (compose f (repeated f (dec times)))))) ; Exercise 1.44 (define (smooth f) (lambda (x) (/ (+ (f (- x dx)) (f x) (f (+ x dx))) 3))) (define (repeated-smooth f times) (repeated smooth times)) ; Exercise 1.45 (define (root n x) (fixed-point-of-transform (lambda (y) (/ x (expt y (dec n)))) (repeated average-damp (log n 2)) 1.0)) ; Exercise 1.46 (define (iter-improve good-enough improve) (lambda (x) (let ((xim (improve x))) (if (good-enough x xim) xim ((iter-improve good-enough improve) xim)))))