Add solutions to exercises from section 1.3

This commit is contained in:
Petar Kapriš 2025-02-04 21:35:51 +01:00
parent a697f52405
commit bc04031dff
18 changed files with 353 additions and 0 deletions

22
ex-1.29.scm Normal file
View file

@ -0,0 +1,22 @@
#lang sicp
; (define (cube x) (* x x x))
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
(define (inc x) (+ 1 x))
(define (simpson f a b n)
(define h (/ (- b a) n))
(define (add-h x) (+ x h))
(define (term i)
(cond ((= i 0) (f a))
((= i n) (f b))
((even? i) (* 2 (f (+ a (* i h)))))
(else (* 4 (f (+ a (* i h)))))))
(* h
(/ 1.0 3)
(sum term 0 inc n)))

8
ex-1.30.scm Normal file
View file

@ -0,0 +1,8 @@
#lang sicp
(define (sum term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (+ result (term a)))))
(iter a 0))

25
ex-1.31.scm Normal file
View file

@ -0,0 +1,25 @@
#lang sicp
(define (product term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (* result (term a)))))
(iter a 1))
(define (pi-prod n)
(define (pi-term i)
(if (even? i)
(/ (+ i 2) (+ i 1))
(/ (+ i 1) (+ i 2))))
(product pi-term 1 inc n))
;(define (inc x) (+ x 1))
(define (factorial n)
(product identity 1 inc n))
(define (product-rec term a next b)
(if (> a b)
1
(* (term a) (product-rec term (next a) next b))))

13
ex-1.32.scm Normal file
View file

@ -0,0 +1,13 @@
#lang sicp
(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))
(define (sum term a next b)
(accumulate + 0 term a next b))
(define (product term a next b)
(accumulate * 1 term a next b))

39
ex-1.33.scm Normal file
View file

@ -0,0 +1,39 @@
#lang sicp
(define (filtered-accumulate combiner
null-value
term
a
next
b
pred?)
(define (iter a result)
(cond ((> a b) result)
((pred? a) (iter (next a)
(combiner result (term a))))
(else (iter (next a) result))))
(iter a null-value))
(define (square x) (* x x))
(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))
(define (prime? n)
(= n (smallest-divisor n)))
(define (prime-square-sum a b)
(filtered-accumulate + 0 square a inc b prime?))
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))
(define (rel-prime-product n)
(define (rel-prime-n? i)
(= (gcd i n) 1))
(filtered-accumulate * 1 identity 1 inc n rel-prime-n?))

4
ex-1.34.txt Normal file
View file

@ -0,0 +1,4 @@
(f f)
(f 2)
(2 2)
Error: 2 is not a procedure

24
ex-1.35.scm Normal file
View file

@ -0,0 +1,24 @@
#lang sicp
(define tolerance 0.00001)
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))
; below is phi
;
; proof: f(x) = 1 + 1/x
; f(phi) = 1 + 1/((1+sqrt(5))/2) = 1 + 2/(1+sqrt(5)) =
; (1+sqrt(5))/(1+sqrt(5)) + 2/(1+sqrt(5)) =
; ( 3+sqrt(5) ) / (1+sqrt(5)) (multiply and divide by (1-sqrt(5)))
; you get: (1+sqrt(5))/2 qed
;
(define phi (fixed-point (lambda (x) (+ 1 (/ 1 x))) 2.0))
(define solution (lambda (x) (+ 1 (/ 1 x))))

28
ex-1.36.scm Normal file
View file

@ -0,0 +1,28 @@
#lang sicp
(define tolerance 0.00001)
(define (fixed-point f guess)
(define new-guess (f guess))
(cond ((< (abs (- guess new-guess)) tolerance)
(display new-guess)
(newline)
(f guess))
(else
(display new-guess)
(newline)
(fixed-point f new-guess))))
; 34 steps without damping
(define solution (fixed-point
(lambda (x) (/ (log 1000)
(log x)))
2.0))
(newline)
(newline)
(newline)
; 9 steps with average damping
(define solution-damped
(fixed-point (lambda (x) (/ (+ x
(/ (log 1000)
(log x)))
2.0))
2.0))

11
ex-1.37.scm Normal file
View file

@ -0,0 +1,11 @@
#lang sicp
(define (cont-frac n d k)
(define (cf-acc n d k i)
(if (= k i)
(/ (n i) (d i))
(/ (n i) (+ (d i) (cf-acc n d k (+ i 1))))))
(cf-acc n d k 0))
; it takes exactly k = 10, for 1/phi to be estimated accurately up to the
; 4th decimal

16
ex-1.38.scm Normal file
View file

@ -0,0 +1,16 @@
#lang sicp
(define (cont-frac n d k)
(define (cf-acc n d k i)
(if (= k i)
(/ (n i) (d i))
(/ (n i) (+ (d i) (cf-acc n d k (+ i 1))))))
(cf-acc n d k 0))
(define (e k)
(+ 2.0 (cont-frac (lambda (i) 1.0)
(lambda (i)
(if (= (remainder i 3) 1)
(* 2.0 (/ (+ i 2) 3))
1.0))
k)))

15
ex-1.39.scm Normal file
View file

@ -0,0 +1,15 @@
#lang sicp
(define (cont-frac n d k)
(define (cf-acc n d k i)
(if (= k i)
(/ (n i) (d i))
(/ (n i) (+ (d i) (cf-acc n d k (+ i 1))))))
(cf-acc n d k 0))
(define (tan-cf x k)
(cont-frac (lambda (i) (if (= i 0)
x
(- (* x x))))
(lambda (i) (+ 1.0 (* 2.0 i)))
k))

7
ex-1.40.scm Normal file
View file

@ -0,0 +1,7 @@
#lang sicp
(define (cubic a b c)
(lambda (x) (+ (* x x x)
(* a x x)
(* b x)
c)))

12
ex-1.41.scm Normal file
View file

@ -0,0 +1,12 @@
#lang sicp
(define (double f)
(lambda (x) (f (f x))))
; double doubles the function application, so when you do
; (double double) you actually get back a function which performs
; a (double (double f)) on a given f, in other words, it
; applies f 4 times. When we do this three times,
; (double (double double)) gives us a function, that for f gives
; (double (double (double (double f)))), which actually
; applies f sixteen times,
; so the result is 5+16 = 21.

4
ex-1.42.scm Normal file
View file

@ -0,0 +1,4 @@
#lang sicp
(define (compose f g)
(lambda (x) (f (g x))))

11
ex-1.43.scm Normal file
View file

@ -0,0 +1,11 @@
#lang sicp
(define (identity x) x)
(define (compose f g)
(lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 0)
identity
(compose f (repeated f (- n 1)))))

9
ex-1.44.scm Normal file
View file

@ -0,0 +1,9 @@
#lang sicp
(define (smooth f)
(define dx 0.0001)
(lambda (x)
(/ (+ (f (- x dx))
(f x)
(f (+ x dx)))
3)))

81
ex-1.45.scm Normal file
View file

@ -0,0 +1,81 @@
#lang sicp
; here, I will prove an upper bound on the number of average
; dampings needed for a given n while calculating nth-root
; in other words, you might need fewer damps than what i prove
; but you definitely have enough damps with this method.
; with n, we need the transform y -> x/y^(n-1)
; one thing which will guarrantee convergence is that the
; derivative of the transform is 0 < d < 1 AFTER the point of
; convergence we're looking for, for example
; derivative of this transform is for SQUARE ROOT is:
; transf: y -> x/y
; deriv: -(x/y^2), which for y>=sqrt(x) will give us a number:
; -1 <= N <= 0, so we can't guarrantee divergence.
; when we average damp, the deriv becomes:
; ( -(x/y^2) + 1 ) / 2, now it lands between 0 and 1.
; for cube root, transform is y->x/y^2, deriv is:
; -2(x/y^3), this lands in the range -2 < d < 0
; if we damp it once, we get the range -0.5 < d < 0.5, so we
; need to damp again to get the range 0.25 < d < 0.75
; in general for calculating the nth-root, we need the
; transform y -> x/y^(n-1), which will have the derivative:
; -(n-1)(x/y^n), the derivative will for y>(nth-root x)
; fall in the range -(n-1) < d < 0.
; Note that when we average damp the function, this range
; becomes -((n-1+1)/2) = -n/2 < d < 0.5, then
; ((-n/2)+1) / 2 < d < 0.75
; when we play around we see that for n-1 = 1, we only need
; one damp, for n-1 = 2 or 3 we need two damps
; for n-1 = 4 or 5 or 6 or 7, we need three, in general
; for n >= 2, we need ceil(log2(n)), average damps
; again, note, we might actually need fewer damps, this is
; just and upper-bound, however, luckily, we can never
; over-damp with this function when coming from the right
; because the upper bound for the derivative values will
; always be 0.5,0.75,0.875,.... < 1.
; so with enought damping we can always get a range of derivs
; in 0 < d < 1.
(define (log2 x)
(/ (log x) (log 2)))
(define tolerance 0.00001)
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))
(define (identity x) x)
(define (compose f g)
(lambda (x) (f (g x))))
(define (repeated f n)
(if (= n 0)
identity
(compose f (repeated f (- n 1)))))
(define (average a b)
(/ (+ a b) 2))
(define (average-damp f)
(lambda (x) (average x (f x))))
; returns a procedure
(define (nth-root n)
(let* ((damp-number (ceiling (log2 n)))
(damps (repeated average-damp damp-number)))
(lambda (x)
(fixed-point (damps (lambda (y)
(/ x (expt y (- n 1)))))
(exact->inexact x)))))

24
ex-1.46.scm Normal file
View file

@ -0,0 +1,24 @@
#lang sicp
(define (iterative-improve good-enough?
improve)
(define (rec-procedure guess)
(define new-guess (improve guess))
(if (good-enough? guess new-guess)
new-guess
(rec-procedure new-guess)))
rec-procedure)
(define (square x)
(* x x))
(define (average a b)
(/ (+ a b)
2))
(define (sqrt x)
(define tolerance 0.000001)
(define (good-enough? guess)
(< (abs (- (square guess) x)) tolerance))
(define (improve guess)
(average guess (/ x guess)))
(iterative-improve good-enough? improve))