]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex1_37.clj
solution to 4.43
[sicp.git] / src / sicp / ex1_37.clj
1 ;; finite continued fraction
2 ;;
3 ;; f = N1/ (D1 + (N2/ D2 + (N3/ D3 + (.... + Nk/Dk))))
4
5 (ns sicp.ex1_37
6   (:use [sicp utils]
7         [clojure.contrib test-is]))
8
9 (defn- calc-cont-frac [n-fn d-fn k cnt]
10   (if (= cnt k)
11     (/ (n-fn cnt) (d-fn cnt))
12     (/ (n-fn cnt) (+ (d-fn cnt) (calc-cont-frac n-fn d-fn k (inc cnt))))))
13
14 (defn cont-frac [n-fn d-fn k]
15   (calc-cont-frac n-fn d-fn k 1))
16
17 (defn good-enough? [x y tolerance]
18   (< (abs (- x y)) tolerance))
19
20 (deftest test-cont-frac-of-all-one
21   (is (good-enough? (/ 1.0 (cont-frac (fn [_] 1.0) (fn [_] 1.0) 100))
22                      1.618
23                      0.01)))
24
25 ;; iterative version
26 ;; work backwards from kth value to 1st value.
27 (defn- calc-cont-frac-i [n-fn d-fn k cnt result]
28   (if (= cnt 0)
29     result
30     (calc-cont-frac-i n-fn d-fn k (dec cnt) (/ (n-fn cnt)
31                                              (+ (d-fn cnt)
32                                                 result)))))
33
34 (defn cont-frac-iter [n-fn d-fn k]
35   (calc-cont-frac-i n-fn d-fn k k 0.0))
36
37 (deftest test-cont-frac-iter-of-all-one
38   (is (good-enough? (/ 1.0 (cont-frac-iter (fn [_] 1.0) (fn [_] 1.0) 100))
39                     1.618
40                     0.01)))