]> git.rkrishnan.org Git - sicp.git/blob - src/main/clojure/sicp/ch1_2.clj
18c14bd38933656b3330b7604724f5f53999cbf3
[sicp.git] / src / main / clojure / sicp / ch1_2.clj
1 (ns sicp.ch1-2
2   (:use (clojure.contrib trace math)))
3
4
5 (defn factorial [n]
6   (if (= n 1)
7     1
8     (* n (factorial (- n 1)))))
9
10 ;; stack friendly version
11 (defn factorial2 [n]
12   (loop [x n acc 1] 
13     (if (= x 1)
14       acc
15       (recur (- x 1) (* acc x)))))
16
17 ;; even better
18 (defn factorial3 [n]
19   (reduce * (range 1 (inc n))))
20
21 ;; (comment
22 ;;  user> (dotrace [factorial] (factorial 3))
23 ;;  TRACE t2701: (factorial 3)
24 ;;  TRACE t2702: |    (factorial 2)
25 ;;  TRACE t2703: |    |    (factorial 1)
26 ;;  TRACE t2703: |    |    => 1
27 ;;  TRACE t2702: |    => 2
28 ;;  TRACE t2701: => 6
29 ;;  6
30 ;; )
31
32 ;; (comment
33 ;;   sicp.chapter1.ch1_2> (dotrace [factorial] (factorial 6))
34 ;;   TRACE t2778: (factorial 6)
35 ;;   TRACE t2779: |    (factorial 5)
36 ;;   TRACE t2780: |    |    (factorial 4)
37 ;;   TRACE t2781: |    |    |    (factorial 3)
38 ;;   TRACE t2782: |    |    |    |    (factorial 2)
39 ;;   TRACE t2783: |    |    |    |    |    (factorial 1)
40 ;;   TRACE t2783: |    |    |    |    |    => 1
41 ;;   TRACE t2782: |    |    |    |    => 2
42 ;;   TRACE t2781: |    |    |    => 6
43 ;;   TRACE t2780: |    |    => 24
44 ;;   TRACE t2779: |    => 120
45 ;;   TRACE t2778: => 720
46 ;;   720
47 ;;   )
48
49 ;; (comment
50 ;;   sicp.chapter1.ch1_2> (dotrace [factorial2] (factorial2 6))
51 ;;   TRACE t2806: (factorial2 6)
52 ;;   TRACE t2806: => 720
53 ;;   720
54 ;;   )
55
56 (defn fact-iter [product counter max-count]
57   (if (> counter max-count)
58     product
59     (fact-iter (* product counter)
60                (inc counter)
61                max-count)))
62
63 (defn factorial [n]
64   (fact-iter 1 1 n))
65
66 ;; (comment
67 ;; user> (dotrace [factorial fact-iter] (factorial 6))
68 ;; TRACE t2378: (factorial 6)
69 ;; TRACE t2379: |    (fact-iter 1 1 6)
70 ;; TRACE t2380: |    |    (fact-iter 1 2 6)
71 ;; TRACE t2381: |    |    |    (fact-iter 2 3 6)
72 ;; TRACE t2382: |    |    |    |    (fact-iter 6 4 6)
73 ;; TRACE t2383: |    |    |    |    |    (fact-iter 24 5 6)
74 ;; TRACE t2384: |    |    |    |    |    |    (fact-iter 120 6 6)
75 ;; TRACE t2385: |    |    |    |    |    |    |    (fact-iter 720 7 6)
76 ;; TRACE t2385: |    |    |    |    |    |    |    => 720
77 ;; TRACE t2384: |    |    |    |    |    |    => 720
78 ;; TRACE t2383: |    |    |    |    |    => 720
79 ;; TRACE t2382: |    |    |    |    => 720
80 ;; TRACE t2381: |    |    |    => 720
81 ;; TRACE t2380: |    |    => 720
82 ;; TRACE t2379: |    => 720
83 ;; TRACE t2378: => 720
84 ;; 720
85 ;; )
86
87 ;; observation: clojure loop-recur construct is essentially the same as
88 ;; the iterative version.
89
90 ;; exercise 1.9
91 (defn ++ [a b]
92   (if (= a 0)
93     b
94     (inc (++ (dec a) b))))
95
96 ;; (comment
97 ;;   This version is a recursive process, where the previous call increments
98 ;;   the sum by 1 and each call decrement the first operand by 1.
99   
100 ;; user> (dotrace [++] (++ 4 5))
101 ;; TRACE t3745: (++ 4 5)
102 ;; TRACE t3746: |    (++ 3 5)
103 ;; TRACE t3747: |    |    (++ 2 5)
104 ;; TRACE t3748: |    |    |    (++ 1 5)
105 ;; TRACE t3749: |    |    |    |    (++ 0 5)
106 ;; TRACE t3749: |    |    |    |    => 5
107 ;; TRACE t3748: |    |    |    => 6
108 ;; TRACE t3747: |    |    => 7
109 ;; TRACE t3746: |    => 8
110 ;; TRACE t3745: => 9
111 ;; 9
112 ;; )
113
114 (defn ++ [a b]
115   (if (= a 0)
116     b
117     (++ (dec a) (inc b))))
118
119 ;; (comment
120   
121 ;; user> (dotrace [++] (++ 4 5))
122 ;; TRACE t3766: (++ 4 5)
123 ;; TRACE t3767: |    (++ 3 6)
124 ;; TRACE t3768: |    |    (++ 2 7)
125 ;; TRACE t3769: |    |    |    (++ 1 8)
126 ;; TRACE t3770: |    |    |    |    (++ 0 9)
127 ;; TRACE t3770: |    |    |    |    => 9
128 ;; TRACE t3769: |    |    |    => 9
129 ;; TRACE t3768: |    |    => 9
130 ;; TRACE t3767: |    => 9
131 ;; TRACE t3766: => 9
132 ;; 9
133 ;; )
134
135 ;; exercise 1.10
136 ;; ackerman functions
137 (defn A [x y]
138   (cond (= y 0) 0
139         (= x 0) (* 2 y)
140         (= y 1) 2
141         :else (A (- x 1)
142                  (A x (- y 1)))))
143
144 (comment
145 user> (A 1 10)
146 1024
147 user> (A 2 4)
148 65536
149 user> (A 3 3)
150 65536
151 )
152
153 (defn f [n] (A 0 n)) ; f(n) = 2n
154 (defn g [n] (A 1 n)) ; g(n) = 2^n
155 ;; (comment
156 ;;   g (n) = A (1,n)
157 ;;         = A (0, A (1, n-1)) = f (A(1,n-1))
158 ;;        = f (f (1,n-2)) 
159 ;;          .....
160 ;;          = f (f (f ... f (1,(n- (n-1)))))
161 ;;            = f (f (f ... 2))
162 ;;              = 2 * (2^(n-1))
163 ;;                = 2^n
164 ;; )
165
166 (defn h [n] (A 2 n)) ; h(n) = 2^(n^2)
167
168 ;; section 1.2.2: Tree Recursion
169 (defn fib [n]
170   (cond (= n 0) 0
171         (= n 1) 1
172         :else (+ (fib (- n 1))
173                  (fib (- n 2)))))
174
175 ;; iterative version
176 (defn fib-iter [a b count]
177   (if (= count 0)
178     b
179     (fib-iter (+ a b) a (dec count))))
180
181 (defn fib [n]
182   (fib-iter 1 0 n))
183
184 ;; example: counting changes
185 (defn first-denomination [kinds-of-coins]
186   (cond (= kinds-of-coins 1) 1
187         (= kinds-of-coins 2) 5
188         (= kinds-of-coins 3) 10
189         (= kinds-of-coins 4) 25
190         (= kinds-of-coins 5) 50))
191
192
193 (defn first-denomination [kinds-of-coins]
194   ({1 1 2 5 3 10 4 25 5 50} kinds-of-coins))
195
196 (defn cc [amount kinds-of-coins]
197   (cond (= amount 0) 1
198         (or (< amount 0) (= kinds-of-coins 0)) 0
199         :else (+ (cc amount (- kinds-of-coins 1))
200                  (cc (- amount
201                         (first-denomination kinds-of-coins))
202                      kinds-of-coins))))
203
204 (defn count-change [amount]
205   (cc amount 5))
206
207 ;; exercise 1.11: A function f is defined by the rule that f(n) = n if n < 3
208 ;;                and f(n) = f(n - 1) + 2f(n  - 2) + 3f(n - 3) if n> 3.
209 ;;                Write a procedure that computes f by means of a recursive
210 ;;                process. Write a procedure that computes f by means of an
211 ;;                iterative process. 
212 (defn f [n]
213   (if (< n 3)
214     n
215     (+ (f (- n 1))
216        (* 2 (f (- n 2)))
217        (* 3 (f (- n 3))))))
218
219 (comment
220 user> (map f (range 10))
221 (0 1 2 4 11 25 59 142 335 796)  
222 )
223
224 ;; ex 1.11: iterative version
225 (defn f-iter [count prev0 prev1 prev2]
226   (if (= count 3)
227     (+ prev0
228        (* 2 prev1)
229        (* 3 prev2))
230     (f-iter (dec count)
231             (+ prev0
232                (* 2 prev1)
233                (* 3 prev2))
234             prev0
235             prev1)))
236
237 (defn f [n]
238   (if (< n 3)
239     n
240     (f-iter n 2 1 0)))
241
242 ;; ex 1.11: iterative version with let
243 (defn f-iter [count prev0 prev1 prev2]
244   (let [res (+ prev0 (* 2 prev1) (* 3 prev2))]
245     (if (= count 3)
246       res
247       (f-iter (dec count)
248               res
249               prev0
250               prev1))))
251
252 ;; exercise 1.12.  The following pattern of numbers is called Pascal's triangle.
253 ;;          1
254 ;;        1   1
255 ;;      1   2   1
256 ;;    1   3   3   1
257 ;;  1   4   6   4   1
258 ;; ...................
259 ;;
260 ;;                 The numbers at the edge of the triangle are all 1, and each
261 ;;                 number inside the triangle is the sum of the two numbers above
262 ;;                 it. Write a procedure that computes elements of Pascal's triangle
263 ;;                 by means of a recursive process. 
264 (defn pascal [row col]
265   (when (<= col row)
266     (if (or (= col 0) (= row col))
267       1
268       (+ (pascal (dec row) col)
269          (pascal (dec row) (dec col))))))
270
271 ;; exercise 1.13:
272 (comment
273 See the pdfs in the directory for the answers.
274 )
275
276 ;; ex 1.13 (contd)
277 (defn fib-approx [n]
278   (let [phi (/ (+ 1 (sqrt 5)) 2)]
279     (/ (expt phi n) (sqrt 5))))
280
281 ;; (comment
282 ;; user> (map fib-approx (range 10))
283 ;; (0.4472135954999579 0.7236067977499789 1.1708203932499368 1.8944271909999157 3.065247584249853 4.959674775249769 8.024922359499623 12.984597134749393 21.009519494249016 33.99411662899841)
284 ;; )
285
286 ;; exercise 1.14: tree of (count-changes 11)
287 (comment
288   See the pdf for the tree representation.
289 )
290
291
292 ;; order of size and computation
293 ;; see PDF, but below is the trace tree.
294 ;; (comment
295 ;; user> (use 'clojure.contrib.trace)
296 ;; nil
297 ;; user> (dotrace [count-change cc] (count-change 11))
298 ;; TRACE t2609: (count-change 11)
299 ;; TRACE t2610: |    (cc 11 5)
300 ;; TRACE t2611: |    |    (cc 11 4)
301 ;; TRACE t2612: |    |    |    (cc 11 3)
302 ;; TRACE t2613: |    |    |    |    (cc 11 2)
303 ;; TRACE t2614: |    |    |    |    |    (cc 11 1)
304 ;; TRACE t2615: |    |    |    |    |    |    (cc 11 0)
305 ;; TRACE t2615: |    |    |    |    |    |    => 0
306 ;; TRACE t2616: |    |    |    |    |    |    (cc 10 1)
307 ;; TRACE t2617: |    |    |    |    |    |    |    (cc 10 0)
308 ;; TRACE t2617: |    |    |    |    |    |    |    => 0
309 ;; TRACE t2618: |    |    |    |    |    |    |    (cc 9 1)
310 ;; TRACE t2619: |    |    |    |    |    |    |    |    (cc 9 0)
311 ;; TRACE t2619: |    |    |    |    |    |    |    |    => 0
312 ;; TRACE t2620: |    |    |    |    |    |    |    |    (cc 8 1)
313 ;; TRACE t2621: |    |    |    |    |    |    |    |    |    (cc 8 0)
314 ;; TRACE t2621: |    |    |    |    |    |    |    |    |    => 0
315 ;; TRACE t2622: |    |    |    |    |    |    |    |    |    (cc 7 1)
316 ;; TRACE t2623: |    |    |    |    |    |    |    |    |    |    (cc 7 0)
317 ;; TRACE t2623: |    |    |    |    |    |    |    |    |    |    => 0
318 ;; TRACE t2624: |    |    |    |    |    |    |    |    |    |    (cc 6 1)
319 ;; TRACE t2625: |    |    |    |    |    |    |    |    |    |    |    (cc 6 0)
320 ;; TRACE t2625: |    |    |    |    |    |    |    |    |    |    |    => 0
321 ;; TRACE t2626: |    |    |    |    |    |    |    |    |    |    |    (cc 5 1)
322 ;; TRACE t2627: |    |    |    |    |    |    |    |    |    |    |    |    (cc 5 0)
323 ;; TRACE t2627: |    |    |    |    |    |    |    |    |    |    |    |    => 0
324 ;; TRACE t2628: |    |    |    |    |    |    |    |    |    |    |    |    (cc 4 1)
325 ;; TRACE t2629: |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 4 0)
326 ;; TRACE t2629: |    |    |    |    |    |    |    |    |    |    |    |    |    => 0
327 ;; TRACE t2630: |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 3 1)
328 ;; TRACE t2631: |    |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 3 0)
329 ;; TRACE t2631: |    |    |    |    |    |    |    |    |    |    |    |    |    |    => 0
330 ;; TRACE t2632: |    |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 2 1)
331 ;; TRACE t2633: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 2 0)
332 ;; TRACE t2633: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    => 0
333 ;; TRACE t2634: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 1 1)
334 ;; TRACE t2635: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 1 0)
335 ;; TRACE t2635: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    => 0
336 ;; TRACE t2636: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    (cc 0 1)
337 ;; TRACE t2636: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    => 1
338 ;; TRACE t2634: |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    => 1
339 ;; TRACE t2632: |    |    |    |    |    |    |    |    |    |    |    |    |    |    => 1
340 ;; TRACE t2630: |    |    |    |    |    |    |    |    |    |    |    |    |    => 1
341 ;; TRACE t2628: |    |    |    |    |    |    |    |    |    |    |    |    => 1
342 ;; TRACE t2626: |    |    |    |    |    |    |    |    |    |    |    => 1
343 ;; TRACE t2624: |    |    |    |    |    |    |    |    |    |    => 1
344 ;; TRACE t2622: |    |    |    |    |    |    |    |    |    => 1
345 ;; TRACE t2620: |    |    |    |    |    |    |    |    => 1
346 ;; TRACE t2618: |    |    |    |    |    |    |    => 1
347 ;; TRACE t2616: |    |    |    |    |    |    => 1
348 ;; TRACE t2614: |    |    |    |    |    => 1
349 ;; TRACE t2637: |    |    |    |    |    (cc 6 2)
350 ;; TRACE t2638: |    |    |    |    |    |    (cc 6 1)
351 ;; TRACE t2639: |    |    |    |    |    |    |    (cc 6 0)
352 ;; TRACE t2639: |    |    |    |    |    |    |    => 0
353 ;; TRACE t2640: |    |    |    |    |    |    |    (cc 5 1)
354 ;; TRACE t2641: |    |    |    |    |    |    |    |    (cc 5 0)
355 ;; TRACE t2641: |    |    |    |    |    |    |    |    => 0
356 ;; TRACE t2642: |    |    |    |    |    |    |    |    (cc 4 1)
357 ;; TRACE t2643: |    |    |    |    |    |    |    |    |    (cc 4 0)
358 ;; TRACE t2643: |    |    |    |    |    |    |    |    |    => 0
359 ;; TRACE t2644: |    |    |    |    |    |    |    |    |    (cc 3 1)
360 ;; TRACE t2645: |    |    |    |    |    |    |    |    |    |    (cc 3 0)
361 ;; TRACE t2645: |    |    |    |    |    |    |    |    |    |    => 0
362 ;; TRACE t2646: |    |    |    |    |    |    |    |    |    |    (cc 2 1)
363 ;; TRACE t2647: |    |    |    |    |    |    |    |    |    |    |    (cc 2 0)
364 ;; TRACE t2647: |    |    |    |    |    |    |    |    |    |    |    => 0
365 ;; TRACE t2648: |    |    |    |    |    |    |    |    |    |    |    (cc 1 1)
366 ;; TRACE t2649: |    |    |    |    |    |    |    |    |    |    |    |    (cc 1 0)
367 ;; TRACE t2649: |    |    |    |    |    |    |    |    |    |    |    |    => 0
368 ;; TRACE t2650: |    |    |    |    |    |    |    |    |    |    |    |    (cc 0 1)
369 ;; TRACE t2650: |    |    |    |    |    |    |    |    |    |    |    |    => 1
370 ;; TRACE t2648: |    |    |    |    |    |    |    |    |    |    |    => 1
371 ;; TRACE t2646: |    |    |    |    |    |    |    |    |    |    => 1
372 ;; TRACE t2644: |    |    |    |    |    |    |    |    |    => 1
373 ;; TRACE t2642: |    |    |    |    |    |    |    |    => 1
374 ;; TRACE t2640: |    |    |    |    |    |    |    => 1
375 ;; TRACE t2638: |    |    |    |    |    |    => 1
376 ;; TRACE t2651: |    |    |    |    |    |    (cc 1 2)
377 ;; TRACE t2652: |    |    |    |    |    |    |    (cc 1 1)
378 ;; TRACE t2653: |    |    |    |    |    |    |    |    (cc 1 0)
379 ;; TRACE t2653: |    |    |    |    |    |    |    |    => 0
380 ;; TRACE t2654: |    |    |    |    |    |    |    |    (cc 0 1)
381 ;; TRACE t2654: |    |    |    |    |    |    |    |    => 1
382 ;; TRACE t2652: |    |    |    |    |    |    |    => 1
383 ;; TRACE t2655: |    |    |    |    |    |    |    (cc -4 2)
384 ;; TRACE t2655: |    |    |    |    |    |    |    => 0
385 ;; TRACE t2651: |    |    |    |    |    |    => 1
386 ;; TRACE t2637: |    |    |    |    |    => 2
387 ;; TRACE t2613: |    |    |    |    => 3
388 ;; TRACE t2656: |    |    |    |    (cc 1 3)
389 ;; TRACE t2657: |    |    |    |    |    (cc 1 2)
390 ;; TRACE t2658: |    |    |    |    |    |    (cc 1 1)
391 ;; TRACE t2659: |    |    |    |    |    |    |    (cc 1 0)
392 ;; TRACE t2659: |    |    |    |    |    |    |    => 0
393 ;; TRACE t2660: |    |    |    |    |    |    |    (cc 0 1)
394 ;; TRACE t2660: |    |    |    |    |    |    |    => 1
395 ;; TRACE t2658: |    |    |    |    |    |    => 1
396 ;; TRACE t2661: |    |    |    |    |    |    (cc -4 2)
397 ;; TRACE t2661: |    |    |    |    |    |    => 0
398 ;; TRACE t2657: |    |    |    |    |    => 1
399 ;; TRACE t2662: |    |    |    |    |    (cc -9 3)
400 ;; TRACE t2662: |    |    |    |    |    => 0
401 ;; TRACE t2656: |    |    |    |    => 1
402 ;; TRACE t2612: |    |    |    => 4
403 ;; TRACE t2663: |    |    |    (cc -14 4)
404 ;; TRACE t2663: |    |    |    => 0
405 ;; TRACE t2611: |    |    => 4
406 ;; TRACE t2664: |    |    (cc -39 5)
407 ;; TRACE t2664: |    |    => 0
408 ;; TRACE t2610: |    => 4
409 ;; TRACE t2609: => 4
410 ;; 4  
411 ;; )
412
413
414 ;; TODO: orders of growth in space and number of steps.
415
416 ;; exercise 1.15: sin (x) calculation
417 ;;    a.  How many times is the procedure p applied when (sine 12.15)
418 ;;        is evaluated?
419 ;;    b.  What is the order of growth in space and number of steps (as
420 ;;        a function of a) used by the process generated by the sine
421 ;;        procedure when (sine a) is evaluated?
422 (defn cube [x] (* x x x))
423
424 (defn p [x] (- (* 3 x) (* 4 (cube x))))
425
426 (defn sine [angle]
427   (if (not (> (abs angle) 0.1))
428     angle
429     (p (sine (/ angle 3.0)))))
430
431 ;; solution to (a) => 5
432 ;; (comment
433 ;; user> (dotrace [p] (sine 12.15))
434 ;; TRACE t2490: (p 0.049999999999999996)
435 ;; TRACE t2490: => 0.1495
436 ;; TRACE t2491: (p 0.1495)
437 ;; TRACE t2491: => 0.4351345505
438 ;; TRACE t2492: (p 0.4351345505)
439 ;; TRACE t2492: => 0.9758465331678772
440 ;; TRACE t2493: (p 0.9758465331678772)
441 ;; TRACE t2493: => -0.7895631144708228
442 ;; TRACE t2494: (p -0.7895631144708228)
443 ;; TRACE t2494: => -0.39980345741334
444 ;; -0.39980345741334
445 ;; )
446
447 ;; solution to b
448 ;; both space and number of steps grows as log3(a) -> log a to the base 3.
449 ;;
450 ;; proof:
451 ;;   a * (1/3)^n <= 0.1
452 ;;   => take log to the base 3 on both the sides.
453
454 ;; Note: Finding the order of space in a recursive process is sort of, equiv
455 ;;       to finding the number of deferred operations. Which is in-turn the
456 ;;       same as the depth of the evaluation tree.
457
458 ;; 1.2.4: exponentiation
459 ;; computing b^n
460
461 ;; iterative
462 (defn expt-iter [base counter product]
463   (if (= counter 0)
464     product
465     (expt-iter base
466                (dec counter)
467                (* product base))))
468
469 (defn myexpt [b n]
470   (expt-iter b n 1))
471
472 (defn myexpt [b n]
473   (if (= n 0)
474     1
475     (* b (myexpt b (dec n)))))
476
477 ;; fast version
478 (defn square [x]
479   (* x x))
480
481 (defn fast-expt [b n]
482   (cond (= n 0) 1
483         (even? n) (square (fast-expt b (/ n 2)))
484         :else (* b (fast-expt b (dec n)))))
485
486 ;; exercise 1.16:
487 (defn myexpt [b n]
488   (expt-iter b n 1))
489
490 (defn expt-iter [b n a]
491   (cond (= n 0) a
492         (even? n) (expt-iter (square b) (/ n 2) a)
493         :else (expt-iter b (- n 1) (* a b))))
494
495 ;; exercise 1.17:
496 (defn mult [a b]
497   (if (= b 0)
498     0
499     (+ a (mult a (- b 1)))))
500
501 ;; double
502 (defn twice [x]
503   (* 2 x))
504
505 (defn half [x]
506   (/ x 2))
507
508 ;; product = 2 * (a * (b/2)) for even b
509 ;;         = a    + (a * (b - 1)) for odd b
510 (defn fast-mult [a b]
511   (cond (= b 0) 0
512         (= b 1) a
513         (even? b) (twice (fast-mult a (half b)))
514         :else (+ a (fast-mult a (- b 1)))))
515
516 ;; exercise 1.18: iterative multiply thru addition
517 ;; the idea is to keep a state variable.
518 (defn fast-mult-iter [a b k]
519   (cond (= b 0) k
520         (even? b) (fast-mult-iter (twice a) (half b) k)
521         :else (fast-mult-iter a (- b 1) (+ k a))))
522
523 (defn fast-mult-new [a b]
524   (fast-mult-iter a b 0))
525
526 ;; (comment
527 ;; user> (dotrace [fast-mult-new fast-mult-iter] (fast-mult-new 2 3))
528 ;; TRACE t2915: (fast-mult-new 2 3)
529 ;; TRACE t2916: |    (fast-mult-iter 2 3 0)
530 ;; TRACE t2917: |    |    (fast-mult-iter 2 2 2)
531 ;; TRACE t2918: |    |    |    (fast-mult-iter 4 1 2)
532 ;; TRACE t2919: |    |    |    |    (fast-mult-iter 4 0 6)
533 ;; TRACE t2919: |    |    |    |    => 6
534 ;; TRACE t2918: |    |    |    => 6
535 ;; TRACE t2917: |    |    => 6
536 ;; TRACE t2916: |    => 6
537 ;; TRACE t2915: => 6
538 ;; 6
539 ;; )
540
541 ;; exercise 1.19: fast fibonacci
542 ;; see the pdf of the notebook scan for the derivation of p' and q'
543 (defn ffib-iter [a b p q count]
544   (cond (= count 0) b
545         (even? count)
546         (ffib-iter a
547                    b
548                    (+ (* p p) (* q q))
549                    (+ (* 2 p q) (* q q))
550                    (/ count 2))
551         :else (ffib-iter (+ (* b q) (* a q) (* a p))
552                          (+ (* b p) (* a q))
553                          p
554                          q
555                          (- count 1))))
556
557 (defn ffib [n]
558   (ffib-iter 1 0 0 1 n))
559