Pages

Thursday, May 5, 2011

Exercises 2.1 - 2.4

Exercise 2.1 Define a better version of make-rat that handles both positive and negative arguments. make-rat should normalize the sign so that if the rational number is positive, both the numerator and denominator are positive, and if the rational number is negative, only the numerator is negative.
The main trick in this problem was to get the signs to line up after your number comes through the gcd procedure. I could have redefined gcd to return only a positive number, but that seemed to be cheating. So I came up with the method below which calls make-rat again. I could have added more conditional checking to get the signs to work, but somehow this was the first solution to come to me.

;;;from chapter 1
(define (square x) (* x x))

;;;from section 1.2.5, for Section 2.1.1
(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))

;; from section 2.1
(define (numer x) (car x))

(define (denom x) (cdr x))

(define (print-rat x)
  (newline)
  (display (numer x))
  (display "/")
  (display (denom x)))

;; original make-rat
(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

;;new, improved make-rat
(define (make-rat n d)
  (let ((g (abs (gcd n d))))
    (cond
     ((and (< n 0) (< d 0)) (make-rat (abs n) (abs d)))
     ((and (> n 0) (< d 0)) (make-rat (- n) (- d)))
     (else (cons (/ n g) (/ d g))))))
Exercise 2.2 Specify a constructor make-point and selectors x-point and y-point that define this representation (of a line segment).
;; Exercise 2.2

(define (make-segment a b) (cons a b))

(define (start-segment a) (car a))

(define (end-segment b) (cdr b))

(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)))

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

;;; test out the procedure

(define s1 (make-point 0 0) (make-point 2 4)

(print-point (midpoing s1))

(1,2)
;Unspecified return value
Exercise 2.3 Implement a representation for rectangles in a plane.
I wasn't sure what I was supposed to provide in term of "abstraction barriers." I decided that was the selectors for the width and height of the rectangles. The first definition of rectangle is defined in terms of two points: the top left and the bottom right. Then I define height and width to calculate those values based on the two points.
;; exercise 2.3
;;first definition
(define (make-rect tl br) (cons tl br))

(define (top-left-rect r) (car r))
(define (bottom-right-rect r) (cdr r))

(define (width-rect r)
    (- (x-point (bottom-right-rect r))
       (x-point (top-left-rect r))))

(define (height-rect r)
    (- (y-point (top-left-rect r))
       (y-point (bottom-right-rect r))))
The second definition of rectangle is defined in terms of an origin point and the size. I use coordinates to represent size, which isn't ideal. The data matches up, but it isn't quite right to talk about the x-point of the width. Still, I didn't think it was necessary to define a new kind of size pair for the purpose of this exercise. Height and width selectors return the values of height and width from the size pair.
;; exercise 2.3

;;second definition
(define (make-rect origin size) (cons origin size))
(define (origin-rect r) (car r))
(define (size-rect r) (cdr r))
(define (width-rect r) (x-point (size-rect r)))
(define (height-rect r) (y-point (size-rect r)))
Finally, calculating area and perimeter in terms of size.
;; these procedures work on either representation of rectangle above
(define (perimeter-rect r) (+ (* 2 (width-rect r)) (* 2 (height-rect r))))
(define (area-rect r) (* (width-rect r) (height-rect r)))
Exercise 2.4 What is the corresponding definition of cdr?
This I just worked through with standard substitution rules until the application became clear.
;;exercise 2.4

(define (cons2 x y)
  (lambda (m) (m x y)))

(define (car2 z)
  (z (lambda (p q) p)))

;;substitution for (car (cons 1 2))

(car (cons 1 2))
(car (lambda (m) (m 1 2)))
((lambda (m) (m 1 2)) (lambda (p q) p))
((lambda (p q) p) 1 2)
(lambda (1 2) 1)
1
;; resulting definition of cdr

(define (cdr2 z)
  (z (lambda (p q) q)))