問題2-2〜3

この二問は平面上の座標を扱う問題です。まずは、問題2-2のコードです。マイナスの座標軸でも正しくmidpointを算出できるかどうかは確認していません。おそらくダメでしょう。

(define (make-segment start-segment end-segment)
  (cons start-segment end-segment))

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

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

(define (make-point x-point y-point)
  (cons x-point y-point))

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

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

(define (midpoint-segment segment)
  (define (calc-midpoint start end)
    (/ (+ start end) 2))
  (make-point (calc-midpoint (x-point (start-segment segment))
                             (x-point (end-segment segment)))
              (calc-midpoint (y-point (start-segment segment))
                             (y-point (end-segment segment)))))

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

(define line-a
  (make-segment (make-point 6 8) (make-point 2 2)))

(print-point (midpoint-segment line-a))

=>(4,5)

次の長方形を扱う問題2-3ですが、長方形を作るときに何を引数で渡すのかが鍵になります。どんなパターンでも、長方形の周囲の長さや面積を求めるロジックに変更がないような「抽象の壁」が求められます。ただ、いろいろと試す時間がなかったので、ひとまず、長方形の左側の縦軸と下側の横軸を引数に渡すようなコードを書きました。

(define (make-rect-1 height-segment width-segment)
  (cons height-segment width-segment))

(define (height-length rect)
  (- (y-point (end-segment (car rect)))
     (y-point (start-segment (car rect)))))

(define (width-length rect)
  (- (x-point (end-segment (cdr rect)))
     (x-point (start-segment (cdr rect)))))

(define (calc-area rect)
  (* (height-length rect)
     (width-length rect)))

(define (calc-perimeter rect)
  (* 2 (+ (height-length rect)
          (width-length rect))))

(define r1 (make-rect-1 (make-segment (make-point 1 1)
                                      (make-point 1 10))
                        (make-segment (make-point 1 1)
                                      (make-point 20 1))))

(calc-area r1)
(calc-perimeter r1)

=>171
=>56

長方形オブジェクトの構成物がこれだとあまり融通が利かないのではとも思いましたが、このあたりについては他の人の解答などを参考にしながら、後日まとめてみようと考えています。