ウォンツテック

そでやまのーと

SICPの問題を解く 23

問題 2.1

consとcar, cdrが出てきた。なるほどリストか。ふむふむ、これはシンプルで強力そうだ。2章終わったらC++で書いた正規表現パーサをschemeで書き直してみようかな。どんな風になるやら。

(define (make-rat n d)                                                          
  (let ((g (gcd n d)))                                                          
    (let ((n-itr (/ n g))                                                       
          (d-itr (/ d g)))                                                      
      (cond ((and (< n-itr 0) (< d-itr 0)) (cons (- n-itr) (- d-itr)))          
            ((and (< n-itr 0) (> d-itr 0)) (cons n-itr d-itr))                  
            ((and (> n-itr 0) (< d-itr 0)) (cons (- n-itr) (- d-itr)))          
            (else (cons n-itr d-itr))))))                                       
(define (numer x) (car x))                                                      
(define (denom x) (cdr x))                                                      
(define (add-rat x y)                                                           
  (make-rat (+ (* (numer x) (denom y)) (* (denom x) (numer y)))                 
            (* (denom x) (denom y))))                                           
(define (sub-rat x y)                                                           
  (make-rat (- (* (numer x) (denom y)) (* (denom x) (numer y)))                 
            (* (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 (gcd a b)                                                               
  (if (= b 0) a                                                                 
      (gcd b (remainder a b))))                                                 
(define (print-rat x)                                                           
  (display (numer x))                                                           
  (display "/")                                                                 
  (display (denom x))                                                           
  (newline))                                                                    
                                                                                
(define x1 (make-rat 2 3))                                                      
(define x2 (make-rat (- 5) 2))                                                  
(define x3 (make-rat (- 1) 6))                                                  
(print-rat (add-rat x1 x2))                                                     
(print-rat (mul-rat x2 x3))
(print-rat (div-rat x3 x1))                                                     
(print-rat (sub-rat x3 x2))