naga:2-1 > 2-16

Todo

2.3長方形の別表現。セレクタの変更で済むようにしないと。
2.6
2.11問題を理解できているか?
2.14問題を理解できているか?
2.15
2.16

Exercise 2.1

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons ((if (< (* n d) 0) - +) (abs (/ n g)))
          (abs (/ d g)))))

Exercise 2.2

(define (make-segment p1 p2)
  (cons p1 p2))
(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 (midpoint-segment s)
  (make-point
   (/ (+ (x-point (start-segment s)) (x-point (end-segment s))) 2)
   (/ (+ (y-point (start-segment s)) (y-point (end-segment s))) 2)))

Exercise 2.3

;; 周囲
(define (rectangle-perimeter r)
  (+ (* (segment-length (v-rectangle r)) 2)
     (* (segment-length (h-rectangle r)) 2)))
;; 面積
(define (rectangle-area r)
  (* (segment-length (v-rectangle r))
     (segment-length (h-rectangle r))))
(define (make-rectangle v h)
  (if (and (have-same-point? v h) (right-angle? v h))
      (cons v h)
      #f))
;;  segmentが同じpointを持つか?
(define (have-same-point? v h)
  (or (same-point? (start-segment v) (start-segment h))
      (same-point? (start-segment v) (end-segment h))
      (same-point? (end-segment v) (start-segment h))
      (same-point? (end-segment v) (end-segment h))))
;;   同じpointか?
(define (same-point? p1 p2)
  (and (= (x-point p1) (x-point p2))
       (= (y-point p1) (y-point p2))))
;;   segmentが直交するか?
(define (right-angle? v h)
  (let ((dvx (- (x-point (end-segment v)) (x-point (start-segment v))))
        (dvy (- (y-point (end-segment v)) (y-point (start-segment v))))
        (dhx (- (x-point (end-segment h)) (x-point (start-segment h))))
        (dhy (- (y-point (end-segment h)) (y-point (start-segment h)))))
    (cond ((or (and (= dvx 0) (= dvy 0)) (and (= dhx 0) (= dhy 0))) #f)
          ((or (and (= dvx 0) (= dhy 0)) (and (= dvy 0) (= dhx 0))) #t)
          ((or (and (not (= dvx 0)) (not (= dhy 0)) (= (/ dvy dvx) (/ dhx dhy)))
               (and (not (= dvy 0)) (not (= dhx 0)) (= (/ dvx dvy) (/ dhy dhx)))) #t)
          (else #f))))
;; selectors for rectangle
(define (v-rectangle r)
  (car r))
(define (h-rectangle r)
  (cdr r))
;; segment長
(define (segment-length s)
  (sqrt (+ (square (- (x-point (start-segment s)) (x-point (end-segment s))))
           (square (- (y-point (start-segment s)) (y-point (end-segment s)))))))

 ;;gosh> (define p00 (make-point 0 0))
;;p00
;;gosh> (define p40 (make-point 4 0))
;;p40
;;gosh> (define p02 (make-point 0 2))
;;p02
;;gosh> (define s0040 (make-segment p00 p40))
;;s0040
;;gosh> (define s0002 (make-segment p00 p02))
;;s0002
;;gosh> (define r (make-rectangle s0040 s0002))
;;r
;;gosh> (rectangle-perimeter r)
;;8.0

別の表現はパス。

Exercise 2.4

;; (car (cons x y))
;;-> (car (lambda (m) (m x y)))              ;;引数(cons x y)を評価
;;-> ((lambda (m) (m x y)) (lambda (p q) p)) ;;carを評価
;;-> ((lambda (p q) p) x y)                  ;;carに引数を適用
;;-> x                                       ;;評価
(define (cons-f x y)
  (lambda (m) (m x y)))
(define (car-f z)
  (z (lambda (p q) p)))
(define (cdr-f z)
  (z (lambda (p q) q)))

;;gosh> (cdr-f (cons-f 'x 'y))
;;y

Exercise 2.5

;; 2と3は互いに素のため(expt 2 a)と(expt 3 b)も互いに素となりa,bの情報を保存できる。
(define (cons-a a b)
  (* (expt 2 a) (expt 3 b)))
(define (car-a n)
  (if (not (= (remainder n 2) 0))
      0
      (+ 1 (car-a (/ n 2)))))
(define (cdr-a n)
  (if (not (= (remainder n 3) 0))
      0
      (+ 1 (cdr-a (/ n 3)))))

;;gosh> (define x (cons-a 7 13))
;;x
;;gosh> x
;;204073344
;;gosh> (car-a x)
;;7
;;gosh> (cdr-a x)
;;13

Exercise 2.6

後日

Exercise 2.7

;; selectors
(define (upper-bound x)
  (max (car x) (cdr x)))
(define (lower-bound x)
  (min (car x) (cdr x)))

Exercise 2.8

;;  difference
(define (sub-interval x y)
    (make-interval (- (upper-bound x) (lower-bound y))
                   (- (lower-bound x) (upper-bound y))))
;;gosh> (define i32 (make-interval 3 2))
;;i32
;;gosh> (define i1-1 (make-interval 1 -1))
;;i1-1
;;gosh> (define r (sub-interval i32 i1-1))
;;r
;;gosh> (upper-bound r)
;;4
;;gosh> (lower-bound r)
;;1

Exercise 2.9

(define (width i)
  (/ (- (upper-bound i) (lower-bound i)) 2))
;;
;;(define w1 (make-interval w1u w1l))
;;(define w2 (make-interval w2u w2l))
;;(width w1)->(w1u-w1l)/2
;;(widht w2)->(w2u-w2l)/2
;;
;;(define w1+w2 (add-interval w1 w2))
;;(width w1+w2)->(/ (- (upper-bound w1+W2) (lower-bound w1+w2)) 2)
;;->((w1u+w2u)-(w1l+w2l))/2->(w1u-w1l)/2+(w2u-w2l)/2
;;->(+ (width w1) (width w2))
;;
;;(define w1-w2 (sub-interval w1 w2))
;;(width w1-w2)->(/ (- (upper-bound w1-w2) (lower-bound w1-w2)) 2)
;;->((w1u-w2l)-(w1l-w2u))/2->(w1u-w1l)/2+(w2u-w2l)/2
;;->(+ (width w1) (width w2))
;;
;;gosh> (define w1 (make-interval 2 1))
;;w1
;;gosh> (define w2 (make-interval 4 3))
;;w2
;;gosh> (define w3 (make-interval -1 -2))
;;w3
;;gosh> (width w1)
;;1/2(
;;gosh> (width w2)
;;1/2
;;gosh> (width w3)
;;1/2
;;gosh> (define w1+w2 (add-interval w1 w2))
;;w1+w2
;;gosh> (define w1+w3 (add-interval w1 w3))
;;w1+w3
;;gosh> (width w1+w2)
;;1
;;gosh> (width w1+w3)
;;1
;;gosh> (define w1*w2 (mul-interval w1 w2))
;;w1*w2
;;gosh> (define w1*w3 (mul-interval w1 w3))
;;w1*w3
;;gosh> (width w1*w2)
;;5/2
;;gosh> (width w1*w3)
;;3/2

Exercise 2.10

(define (div-interval x y)
  (if (not (and (>= (upper-bound y) 0) (<= (lower-bound y) 0)))
      (mul-interval x
                    (make-interval (/ 1.0 (upper-bound y))
                                   (/ 1.0 (lower-bound y))))
      (error "interval spans zero :" y)))

;;gosh> (define w1 (make-interval 2 1))
;;w1
;;gosh> (define w4 (make-interval 1 -1))
;;w4
;;gosh> (div-interval w1 w4)
;;*** ERROR: interval spans zero : (1 . -1)
;;Stack Trace:
;;_______________________________________

Exercise 2.11

(define (mul-interval i1 i2)
 (let ((i1u (upper-bound i1))
       (i1l (lower-bound i1))
       (i2u (upper-bound i2))
       (i2l (lower-bound i2)))
   (cond ((and (>= i1u 0) (>= i1l 0))
          (cond ((and (>= i2u 0) (>= i2l 0))
                 (make-interval (* i1u i2u) (* i1l i2l)))
                ((and (>= i2u 0) (< i2l 0))
                 (make-interval (* i1u i2u) (* i1u i2l)))
                (else (make-interval (* i1l i2u) (* i1u i2l)))))
         ((and (>= i1u 0) (< i1l 0))
          (cond ((and (>= i2u 0) (>= i2l 0))
                 (make-interval (* i1u i2u) (* i1l i2u)))
                ((and (>= i2u 0) (< i2l 0))
                 (make-interval (* i1u i2u) (* i1u i2l)))
                (else (make-interval (* i1l i2l) (* i1u i2l)))))
         (else
          (cond ((and (>= i2u 0) (>= i2l 0))
                 (make-interval (* i1u i2l) (* i1l i2u)))
                ((and (>= i2u 0) (< i2l 0))
                 (make-interval (* i1l i2l) (* i1l i2u)))
                (else (make-interval (* i1l i2l) (* i1u i2u))))))))
;;gosh> (define i21 (make-interval 2 1))
;;i21
;;gosh> (define i1-1 (make-interval 1 -1))
;;i1-1
;;gosh> (define i-1-2 (make-interval -1 -2))
;;i-1-2
;;gosh> (define i21*i21 (mul-interval i21 i21))
;;i21*i21
;;gosh> i21*i21
;;(4 . 1)
;;gosh> (define i21*i1-1 (mul-interval i21 i1-1))
;;i21*i1-1
;;gosh> i21*i1-1
;;(2 . -2)
;;gosh> (define i21*i-1-2 (mul-interval i21 i-1-2))
;;i21*i-1-2
;;gosh> i21*i-1-2
;;(-1 . -4)
;;gosh> (define i1-1*i21 (mul-interval i1-1 i21))
;;i1-1*i21
;;gosh> i1-1*i21
;;(2 . -2)
;;gosh> (define i1-1*i1-1 (mul-interval i1-1 i1-1))
;;i1-1*i1-1
;;gosh> i1-1*i1-1
;;(1 . -1)
;;gosh> (define i1-1*i-1-2 (mul-interval i1-1 i-1-2))
;;i1-1*i-1-2
;;gosh> i1-1*i-1-2
;;(2 . -2)
;;gosh> (define i-1-2*i21 (mul-interval i-1-2 i21))
;;i-1-2*i21
;;gosh> i-1-2*i21
;;(-1 . -4)
;;gosh> (define i-1-2*i1-1 (mul-interval i-1-2 i1-1))
;;i-1-2*i1-1
;;gosh> i-1-2*i1-1
;;(2 . -2)
;;gosh> (define i-1-2*i-1-2 (mul-interval i-1-2 i-1-2))
;;i-1-2*i-1-2
;;gosh> i-1-2*i-1-2
;;(4 . 1)

Exercise 2.12

(define (make-center-percent c p)
  (let ((w (* c (/ p 100))))
    (make-center-width c w)))
(define (percent i)
  (* (/ (width i) (center i)) 100))
;;gosh> (define r6.8+-10% (make-center-percent 6.8 10))
;;r6.8+-10%
;;gosh> (width r6.8+-10%)
;;0.6799999999999997
;;gosh> (percent r6.8+-10%)
;;9.999999999999996

Exercise 2.13

;; i1 = x+dx:x-dx
;; i2 = y+dy:y-dy
;; i1>=0,i2>=0,dx<<x,dy<<yとすると
;; i1*i2 = xy+ydx+xdy+dxdy:xy-ydx-xdy+dxdy
;; dxdyが十分小さいとして良いので
;;       = xy+ydx+ydy:xy-(ydx+xdy)
;; これをpercentで表記するために変形すると
;;       = xy+xy(dx/x+dy/y):xy-xy(dx/x+dy/y)
;; dx/x,dy/yはそれぞれi1,i2のpercentに当たるので
(define (mul-center-percent i1 i2)
  (make-center-percent
   (* (center i1) (center i2))
   (+ (percent i1) (percent i2))))
;;gosh> (define i1 (make-center-percent 100 0.1))
;;i1
;;gosh> (define i2 (make-center-percent 1000 0.2))
;;i2
;;gosh> (define i1*i2 (mul-interval i1 i2))
;;i1*i2
;;gosh> (define i1*i2-simple (mul-center-percent i1 i2))
;;i1*i2-simple
;;gosh> (center i1*i2)
;;100000.20000000001
;;gosh> (percent i1*i2)
;;0.2999994000011927
;;gosh> (center i1*i2-simple)
;;100000.0
;;gosh> (percent i1*i2-simple)
;;0.3

Exercise 2.14

(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)))))
;;以下のように乗算・除算ではwidthが比率として加算される。
;;gosh> (define a (make-center-percent 100 1))
;;an
;;gosh> (define b (make-center-percent 100 2))
;;b
;;gosh> (percent a)
;;1.0
;;gosh> (percent b)
;;2.0
;;gosh> (percent (div-interval a a))
;;1.9998000199980077
;;gosh> (percent (div-interval a b))
;;2.9994001199760016
;;gosh> (percent (div-interval b b))
;;3.998400639744092
;;gosh> (percent (mul-interval a a))
;;1.9998000199980004
;;gosh> (percent (mul-interval a b))
;;2.9994001199760048
;;gosh> (percent (mul-interval b b))
;;3.9984006397441028
;;gosh> (percent (div-interval (make-interval 1 1) a))
;;1.0000000000000036
;;gosh> (percent (mul-interval (make-interval 1 1) a))
;;1.0
;;gosh> (percent (par1 a a))
;;2.999200239928031
;;gosh> (percent (par2 a a))
;;1.000000000000007

Exercise 2.15

後日

Exercise 2.16

後日

タグ:

+ タグ編集
  • タグ:
最終更新:2008年02月17日 17:32
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。