my attempt to do the exercises in sicp.

Monday, July 7, 2008

sicp exercise 2.3



;  Exercise 2.3.  Implement a representation for rectangles in a plane. (Hint: You may want to make use of exercise 2.2.) In terms of your constructors and selectors, create procedures that compute the perimeter and the area of a given rectangle. Now implement a different representation for rectangles.  Can you design your system with suitable abstraction barriers, so that the same perimeter and area procedures will work using either representation?


; square root
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x) x)))

(define (improve guess x)
  (average guess (/ x guess)))


(define (average x y)
  (/ (+ x y) 2))

(define (square x) (* x x))

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

(define (sqrt x)
  (sqrt-iter 1.0 x))


; printing
(define (print-segment s)
  (display "(")
  (print-point (start-point s))
  (display ",")
  (print-point (end-point s))
  (display ")"))

(define (print-point p)
  (display "(")
  (display (x-point p))
  (display ",")
  (display (y-point p))
  (display ")"))

; Abstraction: line segment
(define (make-segment start end)(cons start end))

(define (start-point segment)(car segment))

(define (end-point segment)(cdr segment))

(define (length-segment segment)
  (let ((y-point-start (y-point (start-point segment)))
        (x-point-start (x-point (start-point segment)))
    (y-point-end   (y-point (end-point segment)))
    (x-point-end   (x-point (end-point segment))))
  (cond ((= y-point-start y-point-end )
          (abs (- x-point-start x-point-end )))
        ((= x-point-start x-point-end )
          (abs (- y-point-start y-point-end )))
        (else (sqrt (+ (square (- y-point-end y-point-start))
                   (square (- x-point-end x-point-start))))))))

; Abstraction: point
(define (make-point x y) (cons x y))

(define (x-point p)(car p))

(define (y-point p)(cdr p))

; Abstraction barrier:  get-segment-1 and get-segment-2
(define (perimeter rect)
  (* 2 (+ (length-segment (get-segment-1 rect)) (length-segment (get-segment-2 rect)))))

(define (area rect)
  (* (length-segment (get-segment-1 rect)) (length-segment (get-segment-2 rect))))


#!
; Represntation 1: the rectangle is aligned with x and y axis. so only 2 points on x and y axis are enough to specify the full rectangle.
; x1,x2 are points on x axis. y1,y2 are points on y axis

(define (make-rect x1 x2 y1 y2)
  (cons (cons y1 y2) (cons x1 x2)))

; (x2 y1),(x1 y1)
(define (get-segment-1 rect)
  (make-segment (make-point (cddr rect) (caar rect)) (make-point (cadr rect) (caar rect))))

; (x1 y2),(x1 y1)
(define (get-segment-2 rect)
  (make-segment (make-point (cadr rect) (cdar rect)) (make-point (cadr rect) (caar rect))))

; testing the representation 1
(define myrect (make-rect 2 3 10 20))
(print-segment (get-segment-1 myrect)) (newline)
(display (length-segment (get-segment-1 myrect))) (newline)
(print-segment (get-segment-2 myrect)) (newline)
(display (length-segment (get-segment-2 myrect))) (newline)
(display (perimeter myrect)) (newline)
(display (area myrect)) (newline)
!#


;#!
; Representation 2: the rectangle is represented by 4 points in the plane, whose co-ordinates are input to rectangle constructor. assumption is that x2,y2 is in middle of x1,y1 and x3,y3. then specifying x4,y4 is redundant.

(define (make-rect x1 x2 x3 x4 y1 y2 y3 y4)
  (cons (cons (cons x1 y1) (cons x2 y2)) (cons (cons x3 y3) (cons x4 y4))))

;(x1 y1),(x2 y2)
(define (get-segment-1 rect)
  (make-segment (make-point (caaar rect) (cdaar rect)) (make-point (cadar rect) (cddar rect))))

;(x3 y3),(x2 y2)
(define (get-segment-2 rect)
  (make-segment (make-point (caadr rect) (cdadr rect)) (make-point (cadar rect) (cddar rect))))

; testing the representation 2
(define myrect (make-rect 3 0 4 7 0 4 7 3))
(print-segment (get-segment-1 myrect)) (newline)
(display (length-segment (get-segment-1 myrect))) (newline)
(print-segment (get-segment-2 myrect)) (newline)
(display (length-segment (get-segment-2 myrect))) (newline)
(display (perimeter myrect)) (newline)
(display (area myrect)) (newline)
;!#

; There are two representations of rectangle. Comment one representation at a time and run the program.
; Both representations work fine.

No comments: