SICP 問題 2.1(マイナスを考慮した有理数生成)
さぁ、2章の「データによる抽象の構築」に突入だ!!
まだまだ仕事が忙しくて帰ってくるのは遅いが、地道に進めるぜ!!
【解答】
とりあえず、この問題に至るまでに定義されていた、いくつかの手続きを記載する。
;有理数を生成する (define (make-rat n d) (let ((g (gcd n d))) (cons (/ n g) (/ d g)))) ;有理数の分子を取得する (define (numer x) (car x)) ;有理数の分母を取得する (define (denom x) (cdr x)) ;有理数を加算する (define (add-rat x y) (make-rat (+ (* (numer x) (denom y)) (* (numer y) (denom x))) (* (denom x) (denom y)))) ;有理数を減算する (define (sub-rat x y) (make-rat (- (* (numer x) (denom y)) (* (numer y) (denom x))) (* (denom x) (denom y)))) ;有理数を乗算する (define (mul-rat x y) (make-rat (* (numer x) (numer y)) (* (denom x) (denom y)))) ;有理数を除算する (define (div-rat x y) (make-rat (* (numer x) (denom y)) (* (denom x) (numer y)))) ;有理数を比較する (define (equal-rat? x y) (= (* (numer x) (denom y)) (* (numer y) (denom y)))) ;おまけ。 (define (gcd a b) (if (= b 0) a (gcd b (remainder a b))))
さて、この make-rat を負数を扱えるようにせよとのお達し。
普通に実装してみよう。
(define (make-rat n d) (let* ((g (gcd n d)) (n1 (/ n g)) ;分子 (d1 (/ d g))) ;分母 ;プラスマイナスの掛け合わせだった場合、 ;gcdを評価すると必ず分母側がマイナスになる。 ;これを利用して分母がマイナスだった場合に分子分母に-1を掛けてしまう。 (if (< d1 0) (cons (* -1 (/ n g)) (* -1 (/ d g))) (cons (/ n g) (/ d g)))))
実行してみましょ。
おっけ〜。
gosh> (make-rat 12 -60)
(-1 . 5)
gosh> (make-rat -12 60)
(-1 . 5)
gosh> (make-rat -12 -60)
(1 . 5)
gosh> (make-rat 12 60)
(1 . 5)
gosh>