Arantium Maestum

プログラミング、囲碁、読書の話題

SICPの勉強 問題2.7~11

2.7

(defn make-interval [a b]
  [a b])

(defn upper-bound [c]
  (first c))

(defn lower-bound [c]
  (last c))

2.8

(defn sub-interval [x y]
  (max-interval (- (upper-bound x) (lower-bound y))
                (- (lower-bound x) (upper-bound y))))

2.10

(defn div-interval [x y]
  (if (and (pos? (upper-bound y))
           (neg? (lower-bound y)))
    (throw (Exception. "Division by interval spanning 0"))
    (mul-interval x
                  (make-interval (/ 1.0 (upper-bound y))
                                 (/ 1.0 (lower-bound y))))))

2.11

(defn mul-interval [x y]
  (let [ux (upper-bound x)
        uy (upper-bound y)
        lx (lower-bound x)
        ly (lower-bound y)]
    (cond
      (or (pos? lx) (pos? ly))
      (make-interval (* ux uy) (* lx ly))
      
      (and (pos? ux) (not (pos? uy)))
      (make-interval (* lx ly) (* ux ly))
      
      (and (not (pos? ux)) (pos? uy))
      (make-interval (* lx ly) (* lx uy))
      
      (and (not (pos? ux)) (not (pos? uy)))
      (make-interval (* lx ly) (* ux uy))
      
      :else
      (make-interval (max (* ux uy) (* lx ly)) 
                     (min (* ux ly) (* lx uy))))))

upper-bound・lower-boundが0だった場合どこにいくのか、を考えるのが一番めんどくさかった。