SICP独習会〜有理数の表現(問題2.1)〜

問題2.1

正負の有理数を扱えるようにする。以下が、とりあえず書いてみたソース。

(define (make-rat n d)
  (cond ((or (and (< n 0) (< d 0)) (and (> n 0) (> d 0))) 
		 (cons n d))
	((or (and (< n 0) (> d 0)) (and (> n 0) (< d 0)))
	         (cons -n d))))

で実行結果。


gosh> (print-rat (make-rat -1 2))
ERROR: unbound variable: |-n|
Stack Trace:
_______________________________________
0 (make-rat -1 2)
At line 27 of "(stdin)"

あ〜そうか。「-n」っていうのがだめなんだな。

ってことは、「-1」をかけて、手続きabsを使って値を調整して…

(define (make-rat n d)
  (cond ((or (and (< n 0) (< d 0)) (and (> n 0) (> d 0))) 
		 (cons (abs n) (abs d)))
	((or (and (< n 0) (> d 0)) (and (> n 0) (< d 0)))
	         (cons (* -1 (abs n)) (abs d)))))

こんな感じで。

解答集の答えをみると…

(define (make-rat n d)
  (let ((an (abs n))
        (ad (abs d)))
    (let ((g (gcd an ad)))
      (cons (if (negative? (* n d))
                (* -1 (/ an g))
                (/ an g))
            (/ ad g)))))

私のコードよりきれいだなあ。無駄がないように思える。なんか私の書くSchemeはCっぽいんだよなあ。