Skip to main content.
-->
July 17th, 2007

Solution to SICP Exercise 2.12

Structure and Interpretation of Computer Programs

One solution to Exercise 2.12:

(define (make-center-percent c p)
  (make-center-width c (* c (/ p 100))))

(define (percent i)
  (* (/ (width i) (center i)) 100))

Posted by Ken Dyck as Programming at 6:30 PM MST

3 Comments »

July 16th, 2007

Solution to SICP Exercise 2.11

Structure and Interpretation of Computer Programs

One solution to Exercise 2.11:

(define (mul-interval x y)
  (let* ((lx (lower-bound x))
         (ux (upper-bound x))
         (ly (lower-bound y))
         (uy (upper-bound y))
         (pos-lx? (positive? lx))
         (pos-ux? (positive? ux))
         (pos-ly? (positive? ly))
         (pos-uy? (positive? uy)))
    (cond 
      ; lx ux ly uy  example
      ; ----------------------------------
      ;  +  -  +  +  invalid interval
      ;  +  -  +  -  invalid interval
      ;  +  -  -  +  invalid interval
      ;  +  -  -  -  invalid interval
      ((and pos-lx? (not pos-ux?))
       (error "invalid interval" x))

      ;  +  +  +  -  invalid interval
      ;  -  +  +  -  invalid interval
      ;  -  -  +  -  invalid interval
      ((and pos-ly? (not pos-uy?))
       (error "invalid interval" y))
      
      ;  +  +  +  +  (1.2)(2.3) = (2.6) 
      ((and pos-lx? pos-ux? pos-ly? pos-uy?)
       (make-interval (* lx ly) (* ux uy)))
      
      ;  +  +  -  +  (1.2)(-2.3) = (-4.6)
      ((and pos-lx? pos-ux? (not pos-ly?) pos-uy?)
       (make-interval (* ux ly) (* ux uy)))
      
      ;  +  +  -  -  (1.2)(-2.-1) = (-4.-1) 
      ((and pos-lx? pos-ux? (not pos-ly?) (not pos-uy?))
       (make-interval (* ux ly) (* lx uy)))
      
      ;  -  +  +  +  (-1.2)(2.3) = (-3.6)
      ((and (not pos-lx?) pos-ux? pos-ly? pos-uy?)
       (make-interval (* lx uy) (* ux uy)))
      
      ;  -  +  -  +  (-1.2)(-2.3) = (-4.6) *
      ((and (not pos-lx?) pos-ux? (not pos-ly?) pos-uy?)
       (make-interval (min (* lx uy) (* ux ly))
                      (* ux uy)))
      
      ;  -  +  -  -  (-1.2)(-2.-1) = (-4.2)
      ((and (not pos-lx?) pos-ux? (not pos-ly?) (not pos-uy?))
       (make-interval (* ux ly) (* lx ly)))
      
      ;  -  -  +  +  (-2.-1)(2.3) = (-6.-2)
      ((and (not pos-lx?) (not pos-ux?) pos-ly? pos-uy?)
       (make-interval (* lx uy) (* ux ly)))

      ;  -  -  -  +  (-2.-1)(-2.3) = (-6, 4)
      ((and (not pos-lx?) (not pos-ux?) (not pos-ly?) pos-uy?)
       (make-interval (* lx uy) (* lx ly)))

      ;  -  -  -  -  (-2.-1)(-2.-1) = (1.4)
      ((and (not pos-lx?) (not pos-ux?) (not pos-ly?) (not pos-uy?))
       (make-interval (* ux uy) (* lx ly))))))

Posted by Ken Dyck as Programming at 7:30 PM MST

3 Comments »

July 15th, 2007

Solution to SICP Exercise 2.10

Structure and Interpretation of Computer Programs

One solution to Exercise 2.10:

(define (spans-zero? x)
  (not (or (positive? (lower-bound x)) 
           (negative? (upper-bound x)))))

(define (div-interval x y)
  (if (spans-zero? y)
      (error "Divisor spans zero" y)
      (mul-interval x 
                    (make-interval (/ 1.0 (upper-bound y))
                                   (/ 1.0 (lower-bound y))))))

Posted by Ken Dyck as Programming at 1:34 PM MST

No Comments »

July 8th, 2007

Solution to SICP Exercise 2.9

Structure and Interpretation of Computer Programs

A solution to Exercise 2.9:

Some preliminary definitions:

(upper-bound (make-interval a b)) = a  [1]
(lower-bound (make-interval a b)) = b  [2]

(width i) = (/ (- (upper-bound i) (lower-bound i)) 2)  [3]

(add i1 i2) = (make-interval (+ (upper-bound i1) (upper-bound i2))
                             (+ (lower-bound i1) (lower-bound i2)))  [4]

Rearranging [3]:

(* 2 (width i)) = (- (upper-bound i) (lower-bound i))
(+ (* 2 (width i)) (lower-bound i)) = (upper-bound i)  [5]

From [3]:

(width (add i1 i2)) = (/ (- (upper-bound (add i1 i2))
                            (lower-bound (add i1 i2)))
                         2)

Simplifying with [1], [2] and [4]:

(width (add i1 i2)) = (/ (- (+ (upper-bound i1) 
                               (upper-bound i2))
                            (+ (lower-bound i1) 
                               (lower-bound i2)))
                         2)

Substituting in [5]:

                    = (/ (- (+ (+ (* 2 (width i1)) (lower-bound i1))
                               (+ (* 2 (width i2)) (lower-bound i2)))
                            (+ (lower-bound i1)
                               (lower-bound i2)))
                         2)

                    = (/ (- (+ (* 2 (width i1)) (* 2 (width i2)) 
                               (lower-bound i1) 
                               (lower-bound i2))
                            (+ (lower-bound i1)
                               (lower-bound i2)))
                         2)

All the (lower-bound x)s cancel out, leaving:

                    = (/ (+ (* 2 (width i1)) 
                            (* 2 (width i2)))
                         2)

So do the 2s:

(width (add i1 i2)) = (+ (width i1) (width i2))

Clearly the width of the sum is a function only of the width of the operands.

Posted by Ken Dyck as Programming at 10:31 AM MST

No Comments »

July 7th, 2007

Solution to Exercise SICP 2.8

Structure and Interpretation of Computer Programs

A solution to Exercise 2.8:

The maximum the difference could be is difference between the upper bound of the first interval and the lower bound of the second. The minimum difference is the difference between the lower bound of the first and the upper bound of the second. This holds true even if the second interval is greater than the first or the intervals overlap.

(define (sub-interval x y)
  (make-interval (- (lower-bound x) (upper-bound y))
                 (- (upper-bound x) (lower-bound y))))

Posted by Ken Dyck as Programming at 10:42 AM MST

No Comments »

Solution to SICP Exercise 2.7

Structure and Interpretation of Computer Programs

A solution to Exercise 2.7:

(define (upper-bound interval) (cdr interval))
(define (lower-bound interval) (car interval))

Posted by Ken Dyck as Programming at 10:17 AM MST

1 Comment »

Solution to Exercise SICP 2.6

Structure and Interpretation of Computer Programs

One solution to Exercise 2.6:

(define zero (lambda (f) (lambda (x) x)))

(define (add-1 n)
  (lambda (f) (lambda (x) (f ((n f) x)))))

; (add-1 zero)
; (lambda (f) (lambda (x) (f ((zero f) x))))
; (lambda (f) (lambda (x) (f (((lambda (g) (lambda (y) y)) f) x))))
; (lambda (f) (lambda (x) (f ((lambda (y) y) x))))
; (lambda (f) (lambda (x) (f x)))
(define one
  (lambda (f) (lambda (x) (f x))))

; (add-1 one)
;(lambda (f) (lambda (x) (f ((one f) x))))
;(lambda (f) (lambda (x) (f (((lambda (g) (lambda (y) (g (y)))) f) x))))
;(lambda (f) (lambda (x) (f ((lambda (y) (f (y))) x))))
;(lambda (f) (lambda (x) (f (f (x)))))
(define two
  (lambda (f) (lambda (x) (f (f x)))))

(define (add a b)
  (lambda (f) (lambda (x) ((a f) ((b f) x)))))

; transform Church numerals to integers (for testing)
(define (to-integer n)
  (define (inc x) (+ 1 x))
  ((n inc) 0))

Posted by Ken Dyck as Programming at 9:47 AM MST

2 Comments »