Add solutions to exercises from section 2.1
To be noted: the last two exercises, 2.15 and 2.16 were left unfinished, and will be left for another time.
This commit is contained in:
parent
bc04031dff
commit
1b2b2dfec1
16 changed files with 391 additions and 0 deletions
8
ex-2.01.scm
Normal file
8
ex-2.01.scm
Normal file
|
@ -0,0 +1,8 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-rat n d)
|
||||
(let ((g (gcd n d)))
|
||||
(cond ((= d 0)
|
||||
(error "Cannot make-rat with denominator 0"))
|
||||
((< d 0) (cons (- (/ n g)) (- (/ d g))))
|
||||
(else (cons (/ n g) (/ d g))))))
|
24
ex-2.02.scm
Normal file
24
ex-2.02.scm
Normal file
|
@ -0,0 +1,24 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-segment a b)
|
||||
(cons a b))
|
||||
(define (start-segment s)
|
||||
(car s))
|
||||
(define (end-segment s)
|
||||
(cdr s))
|
||||
|
||||
(define (make-point x y)
|
||||
(cons x y))
|
||||
(define (x-point p)
|
||||
(car p))
|
||||
(define (y-point p)
|
||||
(cdr p))
|
||||
|
||||
(define (average a b)
|
||||
(/ (+ a b) 2.0))
|
||||
|
||||
(define (midpoint-segment s)
|
||||
(make-point (average (x-point (start-segment s))
|
||||
(x-point (end-segment s)))
|
||||
(average (y-point (start-segment s))
|
||||
(y-point (end-segment s)))))
|
34
ex-2.03.scm
Normal file
34
ex-2.03.scm
Normal file
|
@ -0,0 +1,34 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-point x y)
|
||||
(cons x y))
|
||||
(define (x-point p)
|
||||
(car p))
|
||||
(define (y-point p)
|
||||
(cdr p))
|
||||
|
||||
; top-left point, bottom-right point representation
|
||||
(define (tlbr-rect a b)
|
||||
(cons 'tlbr (cons a b)))
|
||||
|
||||
; center point, width, height representation
|
||||
(define (cpwh-rect p w h)
|
||||
(cons 'cpwh
|
||||
(cons p
|
||||
(cons w h))))
|
||||
|
||||
(define (height rect)
|
||||
(cond ((eq? 'cpwh (car rect)) (cdddr rect))
|
||||
(else (abs (- (y-point (cadr rect))
|
||||
(y-point (cddr rect)))))))
|
||||
|
||||
|
||||
(define (width rect)
|
||||
(cond ((eq? 'cpwh (car rect)) (caddr rect))
|
||||
(else (abs (- (x-point (cadr rect))
|
||||
(x-point (cddr rect)))))))
|
||||
|
||||
(define (perimeter rect)
|
||||
(* 2 (+ (width rect) (height rect))))
|
||||
(define (area rect)
|
||||
(* (width rect) (height rect)))
|
4
ex-2.04.scm
Normal file
4
ex-2.04.scm
Normal file
|
@ -0,0 +1,4 @@
|
|||
#lang sicp
|
||||
|
||||
(define (cdr z)
|
||||
(z (lambda (p q) q)))
|
29
ex-2.05.scm
Normal file
29
ex-2.05.scm
Normal file
|
@ -0,0 +1,29 @@
|
|||
#lang sicp
|
||||
|
||||
(define (cons a b)
|
||||
(* (expt 2 a)
|
||||
(expt 3 b)))
|
||||
|
||||
(define (car pair)
|
||||
(if (= (remainder pair 3) 0)
|
||||
(car (/ pair 3))
|
||||
(log2 pair)))
|
||||
|
||||
(define (cdr pair)
|
||||
(if (= (remainder pair 2) 0)
|
||||
(cdr (/ pair 2))
|
||||
(log3 pair)))
|
||||
|
||||
(define (log2 num)
|
||||
(define (aux num acc)
|
||||
(if (<= num 1)
|
||||
acc
|
||||
(aux (/ num 2) (+ acc 1))))
|
||||
(aux num 0))
|
||||
|
||||
(define (log3 num)
|
||||
(define (aux num acc)
|
||||
(if (<= num 1)
|
||||
acc
|
||||
(aux (/ num 3) (+ acc 1))))
|
||||
(aux num 0))
|
14
ex-2.06.scm
Normal file
14
ex-2.06.scm
Normal file
|
@ -0,0 +1,14 @@
|
|||
#lang sicp
|
||||
|
||||
(define one (lambda (f)
|
||||
(lambda (x)
|
||||
(f x))))
|
||||
|
||||
(define two (lambda (f)
|
||||
(lambda (x)
|
||||
(f (f x)))))
|
||||
|
||||
(define (+ a b)
|
||||
(lambda (f)
|
||||
(lambda (x)
|
||||
((a f) ((b f) x)))))
|
7
ex-2.07.scm
Normal file
7
ex-2.07.scm
Normal file
|
@ -0,0 +1,7 @@
|
|||
#lang sicp
|
||||
|
||||
(define (lower-bound i)
|
||||
(car i))
|
||||
|
||||
(define (upper-bound i)
|
||||
(cdr i))
|
15
ex-2.08.scm
Normal file
15
ex-2.08.scm
Normal file
|
@ -0,0 +1,15 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-interval a b) (cons a b))
|
||||
|
||||
(define (lower-bound i)
|
||||
(car i))
|
||||
|
||||
(define (upper-bound i)
|
||||
(cdr i))
|
||||
|
||||
(define (sub-interval a b)
|
||||
(make-interval (- (lower-bound a)
|
||||
(upper-bound b))
|
||||
(- (upper-bound a)
|
||||
(lower-bound b))))
|
31
ex-2.09.scm
Normal file
31
ex-2.09.scm
Normal file
|
@ -0,0 +1,31 @@
|
|||
#lang sicp
|
||||
#|
|
||||
(define (add-interval x y)
|
||||
(make-interval (+ (lower-bound x) (lower-bound y))
|
||||
(+ (upper-bound x) (upper-bound y))))
|
||||
|
||||
(define (sub-interval a b)
|
||||
(make-interval (- (lower-bound a) (upper-bound b))
|
||||
(- (upper-bound a) (lower-bound b))))
|
||||
|
||||
Notice that in add-interval, the lower-bound is low-x + low-y.
|
||||
Meanwhile the higher-bound is high-x + high-y = low-x + width-x
|
||||
+ low-y + width-y = low-sum + (width-x + width-y).
|
||||
So width-sum = width-x + width-y.
|
||||
|
||||
Similar logic applies to sub-interval.
|
||||
|
||||
For mul-interval it's enough to see that
|
||||
(mul-interval (make-interval 1 2) (make-interval 3 4)) =
|
||||
(3 . 8) -> width = 5
|
||||
doesn't have the same width as:
|
||||
(mul-interval (make-interval 3 4) (make-interval 3 4)) =
|
||||
(9 . 16) -> width = 7
|
||||
despite the fact that in both cases, the intervals have widths:
|
||||
1 and 1.
|
||||
|#
|
||||
|
||||
; This code is only here to pass hexlet's test, which I'm not sure is
|
||||
; necessary.
|
||||
(define (width x) (/ (- (upper-bound x) (lower-bound x))
|
||||
2))
|
25
ex-2.10.scm
Normal file
25
ex-2.10.scm
Normal file
|
@ -0,0 +1,25 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-interval a b) (cons a b))
|
||||
|
||||
(define (lower-bound i)
|
||||
(car i))
|
||||
|
||||
(define (upper-bound i)
|
||||
(cdr i))
|
||||
|
||||
(define (mul-interval x y)
|
||||
(let ((p1 (* (lower-bound x) (lower-bound y)))
|
||||
(p2 (* (lower-bound x) (upper-bound y)))
|
||||
(p3 (* (upper-bound x) (lower-bound y)))
|
||||
(p4 (* (upper-bound x) (upper-bound y))))
|
||||
(make-interval (min p1 p2 p3 p4)
|
||||
(max p1 p2 p3 p4))))
|
||||
|
||||
(define (div-interval x y)
|
||||
(if (<= (* (lower-bound y) (upper-bound y)) 0)
|
||||
(error "division by zero")
|
||||
(mul-interval
|
||||
x
|
||||
(make-interval (/ 1.0 (upper-bound y))
|
||||
(/ 1.0 (lower-bound y))))))
|
75
ex-2.11.scm
Normal file
75
ex-2.11.scm
Normal file
|
@ -0,0 +1,75 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-interval a b) (cons a b))
|
||||
|
||||
(define (lower-bound i)
|
||||
(car i))
|
||||
|
||||
(define (upper-bound i)
|
||||
(cdr i))
|
||||
|
||||
|
||||
; explanation for sgn-interval:
|
||||
; an interval has sign 0 if it has negative and non-negative
|
||||
; values (ie. it spans over zero)
|
||||
; a sign of -1 if all of it's values are negative
|
||||
; and a sign of 1 if all of it's values are non-negative
|
||||
(define (sgn-interval a)
|
||||
(let ((low-a (lower-bound a))
|
||||
(upp-a (upper-bound a)))
|
||||
(cond ((< upp-a 0) -1)
|
||||
((>= low-a 0) 1)
|
||||
(else 0))))
|
||||
|
||||
(define (mul-interval x y)
|
||||
(let* ((sgn-x (sgn-interval x))
|
||||
(sgn-y (sgn-interval y))
|
||||
(sgn-pair (cons sgn-x sgn-y)))
|
||||
(cond ((equal? sgn-pair '(-1 . -1))
|
||||
(make-interval (* (upper-bound x)
|
||||
(upper-bound y))
|
||||
(* (lower-bound x)
|
||||
(lower-bound y))))
|
||||
((equal? sgn-pair '(-1 . 0))
|
||||
(make-interval (* (lower-bound x)
|
||||
(upper-bound y))
|
||||
(* (lower-bound x)
|
||||
(lower-bound y))))
|
||||
((equal? sgn-pair '(-1 . 1))
|
||||
(make-interval (* (lower-bound x)
|
||||
(upper-bound y))
|
||||
(* (upper-bound x)
|
||||
(lower-bound y))))
|
||||
((equal? sgn-pair '(0 . -1))
|
||||
(make-interval (* (upper-bound x)
|
||||
(lower-bound y))
|
||||
(* (lower-bound x)
|
||||
(lower-bound y))))
|
||||
; the difficult case
|
||||
((equal? sgn-pair '(0 . 0))
|
||||
(let ((uu (* (upper-bound x) (upper-bound y)))
|
||||
(ul (* (upper-bound x) (lower-bound y)))
|
||||
(lu (* (lower-bound x) (upper-bound y)))
|
||||
(ll (* (lower-bound x) (lower-bound y))))
|
||||
(make-interval (min ul lu)
|
||||
(max uu ll))))
|
||||
((equal? sgn-pair '(0 . 1))
|
||||
(make-interval (* (lower-bound x)
|
||||
(upper-bound y))
|
||||
(* (upper-bound x)
|
||||
(upper-bound y))))
|
||||
((equal? sgn-pair '(1 . -1))
|
||||
(make-interval (* (upper-bound x)
|
||||
(lower-bound y))
|
||||
(* (lower-bound x)
|
||||
(upper-bound y))))
|
||||
((equal? sgn-pair '(1 . 0))
|
||||
(make-interval (* (upper-bound x)
|
||||
(lower-bound y))
|
||||
(* (upper-bound x)
|
||||
(upper-bound y))))
|
||||
((equal? sgn-pair '(1 . 1))
|
||||
(make-interval (* (lower-bound x)
|
||||
(lower-bound y))
|
||||
(* (upper-bound x)
|
||||
(upper-bound y)))))))
|
23
ex-2.12.scm
Normal file
23
ex-2.12.scm
Normal file
|
@ -0,0 +1,23 @@
|
|||
#lang sicp
|
||||
|
||||
(define (make-interval a b) (cons a b))
|
||||
|
||||
(define (lower-bound i)
|
||||
(car i))
|
||||
|
||||
(define (upper-bound i)
|
||||
(cdr i))
|
||||
|
||||
|
||||
(define (make-center-percent c p)
|
||||
(make-interval (- c (* c p 1/100))
|
||||
(+ c (* c p 1/100))))
|
||||
|
||||
(define (center i)
|
||||
(/ (+ (lower-bound i) (upper-bound i)) 2))
|
||||
|
||||
(define (width i)
|
||||
(/ (- (upper-bound i) (lower-bound i)) 2))
|
||||
|
||||
(define (percent i)
|
||||
(* (/ (width i) (center i)) 100))
|
10
ex-2.13.txt
Normal file
10
ex-2.13.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
Let's limit our argument for positive numbers:
|
||||
a+-wa * b+-wb = [(a-wa)*(b-wb), (a+wa)*(b+wb)]
|
||||
[a*b - a*wb - b*wb + wa*wb, a*b + a*wb + b*wa + wa*wb]
|
||||
if we assume wa*wb is insignificantly small, we get:
|
||||
a*b+-(a*wb+b*wa)
|
||||
|
||||
tolerances are the following:
|
||||
ta = wa/a
|
||||
tb = wb/b
|
||||
tab = (a*wb+b*wa)/(a*b) = (a*b*tb + a*b*ta)/(a*b) = ta+tb
|
72
ex-2.14.scm
Normal file
72
ex-2.14.scm
Normal file
|
@ -0,0 +1,72 @@
|
|||
#lang sicp
|
||||
(define make-interval cons)
|
||||
(define (lower-bound i)
|
||||
(car i))
|
||||
|
||||
(define (upper-bound i)
|
||||
(cdr i))
|
||||
|
||||
(define (sub-interval a b)
|
||||
(make-interval (- (lower-bound a)
|
||||
(upper-bound b))
|
||||
(- (upper-bound a)
|
||||
(lower-bound b))))
|
||||
|
||||
(define (mul-interval x y)
|
||||
(let ((p1 (* (lower-bound x) (lower-bound y)))
|
||||
(p2 (* (lower-bound x) (upper-bound y)))
|
||||
(p3 (* (upper-bound x) (lower-bound y)))
|
||||
(p4 (* (upper-bound x) (upper-bound y))))
|
||||
(make-interval (min p1 p2 p3 p4)
|
||||
(max p1 p2 p3 p4))))
|
||||
|
||||
(define (add-interval x y)
|
||||
(make-interval (+ (lower-bound x) (lower-bound y))
|
||||
(+ (upper-bound x) (upper-bound y))))
|
||||
|
||||
(define (div-interval x y)
|
||||
(if (<= (* (lower-bound y) (upper-bound y)) 0)
|
||||
(error "division by zero")
|
||||
(mul-interval
|
||||
x
|
||||
(make-interval (/ 1.0 (upper-bound y))
|
||||
(/ 1.0 (lower-bound y))))))
|
||||
|
||||
|
||||
|
||||
|
||||
(define (par1 r1 r2)
|
||||
(div-interval (mul-interval r1 r2)
|
||||
(add-interval r1 r2)))
|
||||
(define (par2 r1 r2)
|
||||
(let ((one (make-interval 1 1)))
|
||||
(div-interval
|
||||
one (add-interval (div-interval one r1)
|
||||
(div-interval one r2)))))
|
||||
|
||||
(define example-1 (make-interval 1 2))
|
||||
(define example-2 (make-interval 0.999 1.001))
|
||||
|
||||
(div-interval example-1 example-1)
|
||||
;(0.5 . 2.0)
|
||||
(div-interval example-2 example-2)
|
||||
;(0.9980019980019982 . 1.002002002002002)
|
||||
|
||||
; It's simplest to explain this using the previous result
|
||||
; that the tolerance of a product of a*b, is roughly the
|
||||
; sum of the tolerances (if the tolerances are small
|
||||
; relative to the center point)
|
||||
; We can also derive that the tolerance of 1/a is equal to
|
||||
; the tolerance of a.
|
||||
; Proof:
|
||||
; a = [x-w,x+w], t_a = w/x
|
||||
; 1/a = [1/(x+w), 1/(x-w)] =
|
||||
; [(1/(x+w)) * (x-w)/(x-w), (1/(x-w)) * (x+w)/(x+w)] =
|
||||
; [(x-w)/(x^2-w^2), (x+w)/(x^2-w^2)] =
|
||||
; x/(x^2-w^2) +- w/(x^2-w^2)
|
||||
; the tolerance of the product is then:
|
||||
; (w/(x^2-w^2)) / (x/(x^2-w^2)) = w/x, same as t_a.
|
||||
;
|
||||
; This means, using the previous approximation, that the
|
||||
; expression a/a = 1, rather than having a tolerance of 0
|
||||
; is going to have a tolerance doubling that of a.
|
15
ex-2.15-NOT-DONE.txt
Normal file
15
ex-2.15-NOT-DONE.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
This is mostly explained in the previous exercise.
|
||||
|
||||
When it comes to par1 and par2 specifically, we should examine
|
||||
the formulas themselves:
|
||||
((R1+-t1*R1)*(R2+-t2*R2)) / (R1+-t1*R1 + R2+-t2*R2) =
|
||||
(R1*R2 +-t1*R1*R2 +-t2*R2*R1 +-t1*t2*R1*R2) /
|
||||
(R1+R2+-t1*R1+-t2*R2) =
|
||||
(R1*R2 +-t1*R1*R2 +-t2*R2*R1 +-t1*t2*R1*R2) /
|
||||
(R1+R2+-t1*R1+-t2*R2) * (R1+R2-+t1*R1-+t2*R2)/(R1+R2-+t1*R1-+t2*R2) =
|
||||
(R1*R2 +-t1*R1*R2 +-t2*R2*R1 +-t1*t2*R1*R2) /
|
||||
(R1+R2+-t1*R1+-t2*R2) * (R1+R2-+t1*R1-+t2*R2)/(R1+R2-+t1*R1-+t2*R2) =
|
||||
|
||||
|
||||
1 / (1/(R1+-t1)+1/(R2+-t2)) =
|
||||
1 / ((R1-+t1)/(R1^2-t1^2) + (R2-+t2)/(R2^2-t2^2)) =
|
5
ex-2.16-NOT-DONE.txt
Normal file
5
ex-2.16-NOT-DONE.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
One issue is the afformention reuse of intervals, another is
|
||||
floating point arithmetic. In order to solve the problem of making
|
||||
all expressions maximally precise, we would need to make a package that can
|
||||
take a given arithmetic expression and minimize it. This is
|
||||
probaly very hard but not impossible.
|
Loading…
Add table
Reference in a new issue