;; gcd(x,y) = x if y = 0
;; gcd(x,y) = gcd(y,x mod y)
(define gcd
(lambda (x y)
(if (zero? y)
x
(gcd y (remainder x y)))))
;; make rational in simplest form
(define make-ratl
(lambda (x y)
(list (/ x (gcd x y))
(/ y (gcd x y)))))
(define numr
(lambda (x)
(car x)))
(define denr
(lambda (x)
(cadr x)))
(define rprint
(lambda (x)
(if (= (denr x) 1)
(begin
(display (numr x))
(newline))
(begin
(display (numr x))
(display '/)
(display (denr x))
(newline)))))
;; a/b * c/d = a*c / b*d
(define r*
(lambda (x y)
(make-ratl (* (numr x) (numr y))
(* (denr x) (denr y)))))
;; a/b + c/d = (a/b * d/d) + (c/d * b/b) = (a*d + c*b) / (b*d)
(define r+
(lambda (x y)
(make-ratl (+ (* (numr x) (denr y))
(* (numr y) (denr x)))
(* (denr x) (denr y)))))
;; a/b - c/d = (a/b * d/d) - (c/d * b/b) = (a*d - c*b) / (b*d)
(define r-
(lambda (x y)
(make-ratl (- (* (numr x) (denr y))
(* (numr y) (denr x)))
(* (denr x) (denr y)))))
;; 1/(a/b) = b/a
(define rinvert
(lambda (x)
(make-ratl (denr x) (numr x))))
;; a/b / c/d = a/b * d/c
(define r/
(lambda (x y)
(r* x (rinvert y))))
;; a/b = c/d iff a*d = b*c
(define r=
(lambda (x y)
(= (* (numr x) (denr y)) (* (numr y) (denr x)))))