SICP問題2.1

まずは英語の復習。

  • cons … Construct
  • car … Contents of Address part of Register
  • cdr … Contents of Decrement part of Register
  • 有理数 … rational number
  • 無理数 … irrational number
  • 加える … add
  • 減ずる … subtract
  • 乗ずる … multiply
  • 除する … divide
  • 分母 … denominator
  • 分子 … numerator, molecule

正負両方の引数を扱う改良版make-rat

(define (make-rat n d)
  (define (minus?)
    (not (or (and (<= 0 n) (<= 0 d)) (and (> 0 n) (> 0 d)))))
  (define (normalize_numer)
    (if (minus?)
	(if (<= 0 n) 
	    (* -1 n)
	    n)
	(abs n)))
  (let ((g (gcd n d)))
    (cons (/ (normalize_numer) g)
	  (/ (abs d) g))))

他の人の回答でもと思って検索してみる。

(define (make-rat+ n d)
 (let ((g (gcd (abs n) (abs d))))
    (if (< d 0)
        (cons (/ (- n) g) (/ (- d) g))
        (cons (/ n g) (/ d g)))))
http://sicp.naochan.com/memo.pl?p=%CC%E4%C2%EA2.1

えーっと、

(d < 0)
(n < 0) => (- n) => (0 - n) => 正の数 … 分子は有理数が正の場合は正
(n >= 0) => (- n) => (0 - n) => 負の数 … 分子は有理数が負の場合は負
(- d) => (0 - d) => 正の数 … 分母は常に正
(d >= 0)
(n < 0) => 負の数 … 分子は有理数が負の場合は負
(n >= 0) => 正の数 … 分子は有理数が正の場合は正
d => … 分母は常に正
ということで、条件を満たしている。

うーん。頭いいなぁ。

SICP問題2.2

線分の構成子と選択子

(define (make-segment start-point end-point)
  (cons start-point end-point))
(define (start-segment segment)
  (car segment))
(define (end-segment segment)
  (cdr segment))

点の構成子と選択子

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

中間点を求める手続き

(define (midpoint-segment segment)
  (make-point (average (x-point (start-segment segment))
		       (x-point (end-segment segment)))
	      (average (y-point (start-segment segment))
		       (y-point (end-segment segment)))))