SICP 第二章第一节 习题 2.1-2.16

时间:2021-11-17 19:31:18

2.1
(define (make-rat n d)
  (let ((abs-n (abs n))
        (abs-d (abs d))
        (g (gcd (abs n) (abs d))))
    (if (positive? (* n d))
        (cons (/ abs-n g) (/ abs-d g))
        (cons (* (/ abs-n g) (- 1)) (/ abs-d g)))))
2.2
(define (make-segment x y)
  (cons x y))
(define (start-segment seg)
  (car seg))
(define (end-segment seg)
  (cdr seg))
(define (x-point p)
  (car p))
(define (y-point p)
  (cdr p))
(define (midpoint-segment seg)
  (cons (/(+(x-point(start-segment seg))(x-point(end-segment seg)))2)
        (/(+(y-point(start-segment seg))(y-point(end-segment seg)))2)))
(define (print-point p)
  (newline)
  (display "(")
  (display (x-point p))
  (display ",")
  (display (y-point p))
  (display ")"))
2.3
(define (perimeter rec)
  (* 2 (+ (width-rec rec) (height-rec rec))))
(define (area rec)
  (* (width-rec rec)(height-rec rec)))
(1)
(define (make-rec p1 p2)
  (make-segment p1 p2))
(define (width-rec rec)
  (abs (-(x-point (start-segment rec))(x-point (end-segment rec)))))
(define (height-rec rec)
  (abs (-(y-point (start-segment rec))(y-point (end-segment rec)))))
(2)
(define (make-rec x1 y1 x2 y2)
  (cons (cons x1 y1)(cons x2 y2)))
(define (width-rec rec)
  (abs(-(car(car rec))(car(cdr rec)))))
(define (height-rec rec)
  (abs(-(cdr(car rec))(cdr(cdr rec)))))
2.4
证明之:
(car (cons x y))
->((cons x y) (lambda (p q) p))
->((lambda (p q) p) x y)
->x
(define (cdr z)
  (z (lambda (p q) q)))
2.5
(define (cons x y)
  (* (fast-expt 2 x)(fast-expt 3 y)))
(define (car r)
  (define (ar r c)
    (if(not(=(remainder r 2)0))
       c
       (ar (/ r 2) (+ c 1))))
  (ar r 0))
(define (cdr r)
    (define (ar r c)
    (if(not(=(remainder r 3)0))
       c
       (ar (/ r 3) (+ c 1))))
  (ar r 0))
2.6
one=(add-1 zero)
->(lambda (f)(lambda (x)(f(((lambda(f)(lambda(x)x))f)x))))
->(lambda (f)(lambda (x)(f((lambda(x)x)x))))
->(lambda (f)(lambda (x)(f x)))
two=(add-1 one)
->(lambda (f)(lambda (x)(f((f x)))))
2.7
(define (make-interval a b)
  (cons a b))
(define (upper-bound interval)
  (cdr interval))
(define (lower-bound interval)
  (car interval))
2.8
(define (sub-interval x y)
  (make-interval (-(lower-bound x)(upper-bound y))
                 (-(upper-bound x)(lower-bound y))))
2.9
证明:
width1=(up1-low1)/2
width2=(up2-low2)/2
(low3,up3)=(low1,up1)-(low2,up2)=(low1-up2,up1-low2)
width3=(up1-low1+up2-low2)/2=width1+width2
(low4,up4)=(low1,up1)+(low2,up2)=(low1+low2,up1+up2)
width4=(up1+up2-low1-low2)/2=width1+width2
对于乘除就不举例子了
2.10
(define (div-interval x y)
  (if (< (*(lower-bound y)(upper-bound y)) 0)
      (display "illegal")
      (mul-interval x
                (make-interval (/ 1.0 (upper-bound y))
                               (/ 1.0 (lower-bound y))))))
2.11
对于(a,b)有三种情况
1.a<0,b<0;2.a<0,b>0;3.a>0,b>0
对于乘法来说一共有9种情况。
(define (mul-interval x y)
  (define (less? a)
    (if (or(< (upper-bound a) 0)(= (upper-bound a) 0))
        #t
        #f))
  (define (mid? a)
    (if (and(< (lower-bound a) 0)(> (upper-bound a) 0))
        #t
        #f))
  (define (more? a)
    (if (or(> (lower-bound a) 0)(= (lower-bound a) 0))
        #t
        #f))
  (cond ((and(less? x)(less? y))(make-interval (* (upper-bound x)(upper-bound y))
                                               (* (lower-bound x)(lower-bound y))))
        ((and(less? x)(mid? y))(make-interval (* (lower-bound x)(upper-bound y))
                                               (* (upper-bound x)(lower-bound y))))
        ((and(less? x)(more? y))(make-interval (* (lower-bound x)(upper-bound y))
                                               (* (upper-bound x)(lower-bound y))))
        ((and(mid? x)(less? y))(make-interval (* (upper-bound x)(lower-bound y))
                                               (* (lower-bound x)(lower-bound y))))
        ((and(mid? x)(mid? y))(let((p1(* (upper-bound x)(upper-bound y)))
                                                  (p2(* (upper-bound x)(lower-bound y)))
                                                  (p3(* (lower-bound x)(upper-bound y)))
                                                  (p4(* (lower-bound x)(lower-bound y))))
                                               (make-interval (min p1 p2 p3 p4)
                                                              (max p1 p2 p3 p4))))
        ((and(mid? x)(more? y))(make-interval (* (lower-bound x)(upper-bound y))
                                               (* (upper-bound x)(upper-bound y))))
        ((and(more? x)(less? y))(make-interval (* (upper-bound x)(lower-bound y))
                                               (* (lower-bound x)(upper-bound y))))
        ((and(more? x)(mid? y))(make-interval (* (upper-bound x)(lower-bound y))
                                               (* (upper-bound x)(upper-bound y))))
        ((and(more? x)(more? y))(make-interval (* (lower-bound x)(lower-bound y))
                                               (* (upper-bound x)(upper-bound y))))))
2.12
(define (make-center-percent c p)
  (make-interval (- c (/(* p c)100))(+ c(/(* p c)100))))
(define (percent i)
  (* 100 (/(width i) (center i))))
2.13
a(Ca,Pa)=(Ca*(1-Pa/2),Ca*(1+Pa/2)),b(Cb,Pb)=(Cb*(1-Pb/2),Cb*(1+Pb/2))
a*b=(Ca*(1-Pa/2)*Cb*(1-Pb/2),Ca*(1+Pa/2)*Cb*(1+Pb/2))
   =(Ca*Cb*(1-(Pa+Pb)/2+Pa*Pb/4,Ca*Cb*(1+(Pa+Pb)/2+Pa*Pb/4)Pa*Pb非常小,忽略掉
   =(Ca*Cb*(1-(Pa+Pb)/2,Ca*Cb*(1+(Pa+Pb)/2)
即(Ca*Cb,Pa+Pb)
2.14
> (define r1 (make-interval 100 200))
> (define r2 (make-interval 100 300))
> (par1 r1 r2)
(20.0 . 300.0)
> (par2 r1 r2)
(50.0 . 120.0)
两种方法产生的结果完全不同哦
(1)r1=(99.99,100.01),r2=(199.8,200.02)
> (par1 r1 r2)
(66.64666933306668 . 66.68666933360004)
> (par2 r1 r2)
(66.66 . 66.67333333333335)
(2)r1=(99,101),r2=(198,202)
> (par1 r1 r2)
(64.6930693069307 . 68.69360269360269)
> (par2 r1 r2)
(66.0 . 67.33333333333334)
par1误差要比par2大
2.15
par1比par2差,par1中r1、r2各出现两次,而且这两个r1(r2)是独立的,独立变量出现的次数越少,精度越高
2.16
既然r1、r2独立性导致了这种问题,那么我们限制r1、r2的独立性即可,由+、-、*、/运算的代码可知,所得结果的上界和下界
是参数上下界的函数,那么我们就可以:
设(f r(1) r(2)……r(n))为一区间函数,对于每个r(k)都可取(lower-bound r(k))和(upper-bound r(k)
一共有2^n种组合方式,称为集合R,那么fr(1) r(2)……r(n))=(min(R),max(R))
(define (par2 r1 r2)
  (/ 1(+ (/ 1 r1) (/ 1 r2))))
(define (par1 r1 r2)
  (/ (* r1 r2)(+ r1 r2)))
(define (par f r1 r2)
  (let ((p1 (f (lower-bound r1)(lower-bound r2)))
        (p2 (f (lower-bound r1)(upper-bound r2)))
        (p3 (f (upper-bound r1)(lower-bound r2)))
        (p4 (f (upper-bound r1)(upper-bound r2))))
    (make-interval (min p1 p2 p3 p4)
                   (max p1 p2 p3 p4))))