1 (ns sicp.chapter1.ch1_2
2 (:use (clojure.contrib trace math)))
8 (* n (factorial (- n 1)))))
10 ;; stack friendly version
15 (recur (- x 1) (* acc x)))))
19 (reduce * (range 1 (inc n))))
22 user> (dotrace [factorial] (factorial 3))
23 TRACE t2701: (factorial 3)
24 TRACE t2702: | (factorial 2)
25 TRACE t2703: | | (factorial 1)
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
50 sicp.chapter1.ch1_2> (dotrace [factorial2] (factorial2 6))
51 TRACE t2806: (factorial2 6)
56 (defn fact-iter [product counter max-count]
57 (if (> counter max-count)
59 (fact-iter (* product counter)
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
87 ;; observation: clojure loop-recur construct is essentially the same as
88 ;; the iterative version.
94 (inc (++ (dec a) b))))
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.
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
116 (++ (dec a) (inc b))))
120 user> (dotrace [++] (++ 4 5))
121 TRACE t3766: (++ 4 5)
122 TRACE t3767: | (++ 3 6)
123 TRACE t3768: | | (++ 2 7)
124 TRACE t3769: | | | (++ 1 8)
125 TRACE t3770: | | | | (++ 0 9)
126 TRACE t3770: | | | | => 9
127 TRACE t3769: | | | => 9
128 TRACE t3768: | | => 9
135 ;; ackerman functions
152 (defn f [n] (A 0 n)) ; f(n) = 2n
153 (defn g [n] (A 1 n)) ; g(n) = 2^n
156 = A (0, A (1, n-1)) = f (A(1,n-1))
159 = f (f (f ... f (1,(n- (n-1)))))
165 (defn h [n] (A 2 n)) ; h(n) = 2^(n^2)
167 ;; section 1.2.2: Tree Recursion
171 :else (+ (fib (- n 1))
178 (defn fib-iter [a b count]
181 (fib-iter (+ a b) a (dec count))))
183 ;; example: counting changes
184 (defn count-change [amount]
187 (defn cc [amount kinds-of-coins]
189 (or (< amount 0) (= kinds-of-coins 0)) 0
190 :else (+ (cc amount (- kinds-of-coins 1))
192 (first-denomination kinds-of-coins))
195 (defn first-denomination [kinds-of-coins]
196 (cond (= kinds-of-coins 1) 1
197 (= kinds-of-coins 2) 5
198 (= kinds-of-coins 3) 10
199 (= kinds-of-coins 4) 25
200 (= kinds-of-coins 5) 50))
202 (defn first-denomination [kinds-of-coins]
203 ({1 1 2 5 3 10 4 25 5 50} kinds-of-coins))
205 ;; exercise 1.11: A function f is defined by the rule that f(n) = n if n < 3
206 ;; and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n> 3.
207 ;; Write a procedure that computes f by means of a recursive
208 ;; process. Write a procedure that computes f by means of an
209 ;; iterative process.
218 user> (map f (range 10))
219 (0 1 2 4 11 25 59 142 335 796)
222 ;; ex 1.11: iterative version
228 (defn f-iter [count prev0 prev1 prev2]
240 ;; ex 1.11: iterative version with let
241 (defn f-iter [count prev0 prev1 prev2]
242 (let [res (+ prev0 (* 2 prev1) (* 3 prev2))]
250 ;; exercise 1.12. The following pattern of numbers is called Pascal's triangle.
256 ;; ...................
258 ;; The numbers at the edge of the triangle are all 1, and each
259 ;; number inside the triangle is the sum of the two numbers above
260 ;; it. Write a procedure that computes elements of Pascal's triangle
261 ;; by means of a recursive process.
262 (defn pascal [row col]
264 (if (or (= col 0) (= row col))
266 (+ (pascal (dec row) col)
267 (pascal (dec row) (dec col))))))
271 See the pdfs in the directory for the answers.
276 (let [phi (/ (+ 1 (sqrt 5)) 2)]
277 (/ (expt phi n) (sqrt 5))))
280 user> (map fib-approx (range 10))
281 (0.4472135954999579 0.7236067977499789 1.1708203932499368 1.8944271909999157 3.065247584249853 4.959674775249769 8.024922359499623 12.984597134749393 21.009519494249016 33.99411662899841)
284 ;; exercise 1.14: tree of (count-changes 11)
286 See the pdf for the tree representation.
290 ;; order of size and computation
291 ;; see PDF, but below is the trace tree.
293 user> (use 'clojure.contrib.trace)
295 user> (dotrace [count-change cc] (count-change 11))
296 TRACE t2609: (count-change 11)
297 TRACE t2610: | (cc 11 5)
298 TRACE t2611: | | (cc 11 4)
299 TRACE t2612: | | | (cc 11 3)
300 TRACE t2613: | | | | (cc 11 2)
301 TRACE t2614: | | | | | (cc 11 1)
302 TRACE t2615: | | | | | | (cc 11 0)
303 TRACE t2615: | | | | | | => 0
304 TRACE t2616: | | | | | | (cc 10 1)
305 TRACE t2617: | | | | | | | (cc 10 0)
306 TRACE t2617: | | | | | | | => 0
307 TRACE t2618: | | | | | | | (cc 9 1)
308 TRACE t2619: | | | | | | | | (cc 9 0)
309 TRACE t2619: | | | | | | | | => 0
310 TRACE t2620: | | | | | | | | (cc 8 1)
311 TRACE t2621: | | | | | | | | | (cc 8 0)
312 TRACE t2621: | | | | | | | | | => 0
313 TRACE t2622: | | | | | | | | | (cc 7 1)
314 TRACE t2623: | | | | | | | | | | (cc 7 0)
315 TRACE t2623: | | | | | | | | | | => 0
316 TRACE t2624: | | | | | | | | | | (cc 6 1)
317 TRACE t2625: | | | | | | | | | | | (cc 6 0)
318 TRACE t2625: | | | | | | | | | | | => 0
319 TRACE t2626: | | | | | | | | | | | (cc 5 1)
320 TRACE t2627: | | | | | | | | | | | | (cc 5 0)
321 TRACE t2627: | | | | | | | | | | | | => 0
322 TRACE t2628: | | | | | | | | | | | | (cc 4 1)
323 TRACE t2629: | | | | | | | | | | | | | (cc 4 0)
324 TRACE t2629: | | | | | | | | | | | | | => 0
325 TRACE t2630: | | | | | | | | | | | | | (cc 3 1)
326 TRACE t2631: | | | | | | | | | | | | | | (cc 3 0)
327 TRACE t2631: | | | | | | | | | | | | | | => 0
328 TRACE t2632: | | | | | | | | | | | | | | (cc 2 1)
329 TRACE t2633: | | | | | | | | | | | | | | | (cc 2 0)
330 TRACE t2633: | | | | | | | | | | | | | | | => 0
331 TRACE t2634: | | | | | | | | | | | | | | | (cc 1 1)
332 TRACE t2635: | | | | | | | | | | | | | | | | (cc 1 0)
333 TRACE t2635: | | | | | | | | | | | | | | | | => 0
334 TRACE t2636: | | | | | | | | | | | | | | | | (cc 0 1)
335 TRACE t2636: | | | | | | | | | | | | | | | | => 1
336 TRACE t2634: | | | | | | | | | | | | | | | => 1
337 TRACE t2632: | | | | | | | | | | | | | | => 1
338 TRACE t2630: | | | | | | | | | | | | | => 1
339 TRACE t2628: | | | | | | | | | | | | => 1
340 TRACE t2626: | | | | | | | | | | | => 1
341 TRACE t2624: | | | | | | | | | | => 1
342 TRACE t2622: | | | | | | | | | => 1
343 TRACE t2620: | | | | | | | | => 1
344 TRACE t2618: | | | | | | | => 1
345 TRACE t2616: | | | | | | => 1
346 TRACE t2614: | | | | | => 1
347 TRACE t2637: | | | | | (cc 6 2)
348 TRACE t2638: | | | | | | (cc 6 1)
349 TRACE t2639: | | | | | | | (cc 6 0)
350 TRACE t2639: | | | | | | | => 0
351 TRACE t2640: | | | | | | | (cc 5 1)
352 TRACE t2641: | | | | | | | | (cc 5 0)
353 TRACE t2641: | | | | | | | | => 0
354 TRACE t2642: | | | | | | | | (cc 4 1)
355 TRACE t2643: | | | | | | | | | (cc 4 0)
356 TRACE t2643: | | | | | | | | | => 0
357 TRACE t2644: | | | | | | | | | (cc 3 1)
358 TRACE t2645: | | | | | | | | | | (cc 3 0)
359 TRACE t2645: | | | | | | | | | | => 0
360 TRACE t2646: | | | | | | | | | | (cc 2 1)
361 TRACE t2647: | | | | | | | | | | | (cc 2 0)
362 TRACE t2647: | | | | | | | | | | | => 0
363 TRACE t2648: | | | | | | | | | | | (cc 1 1)
364 TRACE t2649: | | | | | | | | | | | | (cc 1 0)
365 TRACE t2649: | | | | | | | | | | | | => 0
366 TRACE t2650: | | | | | | | | | | | | (cc 0 1)
367 TRACE t2650: | | | | | | | | | | | | => 1
368 TRACE t2648: | | | | | | | | | | | => 1
369 TRACE t2646: | | | | | | | | | | => 1
370 TRACE t2644: | | | | | | | | | => 1
371 TRACE t2642: | | | | | | | | => 1
372 TRACE t2640: | | | | | | | => 1
373 TRACE t2638: | | | | | | => 1
374 TRACE t2651: | | | | | | (cc 1 2)
375 TRACE t2652: | | | | | | | (cc 1 1)
376 TRACE t2653: | | | | | | | | (cc 1 0)
377 TRACE t2653: | | | | | | | | => 0
378 TRACE t2654: | | | | | | | | (cc 0 1)
379 TRACE t2654: | | | | | | | | => 1
380 TRACE t2652: | | | | | | | => 1
381 TRACE t2655: | | | | | | | (cc -4 2)
382 TRACE t2655: | | | | | | | => 0
383 TRACE t2651: | | | | | | => 1
384 TRACE t2637: | | | | | => 2
385 TRACE t2613: | | | | => 3
386 TRACE t2656: | | | | (cc 1 3)
387 TRACE t2657: | | | | | (cc 1 2)
388 TRACE t2658: | | | | | | (cc 1 1)
389 TRACE t2659: | | | | | | | (cc 1 0)
390 TRACE t2659: | | | | | | | => 0
391 TRACE t2660: | | | | | | | (cc 0 1)
392 TRACE t2660: | | | | | | | => 1
393 TRACE t2658: | | | | | | => 1
394 TRACE t2661: | | | | | | (cc -4 2)
395 TRACE t2661: | | | | | | => 0
396 TRACE t2657: | | | | | => 1
397 TRACE t2662: | | | | | (cc -9 3)
398 TRACE t2662: | | | | | => 0
399 TRACE t2656: | | | | => 1
400 TRACE t2612: | | | => 4
401 TRACE t2663: | | | (cc -14 4)
402 TRACE t2663: | | | => 0
403 TRACE t2611: | | => 4
404 TRACE t2664: | | (cc -39 5)
405 TRACE t2664: | | => 0
410 ;; TODO: orders of growth in space and number of steps.
413 ;; exercise 1.15: sin (x) calculation
414 ;; a. How many times is the procedure p applied when (sine 12.15)
416 ;; b. What is the order of growth in space and number of steps (as
417 ;; a function of a) used by the process generated by the sine
418 ;; procedure when (sine a) is evaluated?
419 (defn cube [x] (* x x x))
421 (defn p [x] (- (* 3 x) (* 4 (cube x))))
424 (if (not (> (abs angle) 0.1))
426 (p (sine (/ angle 3.0)))))
428 ;; solution to (a) => 5
430 user> (dotrace [p] (sine 12.15))
431 TRACE t2490: (p 0.049999999999999996)
432 TRACE t2490: => 0.1495
433 TRACE t2491: (p 0.1495)
434 TRACE t2491: => 0.4351345505
435 TRACE t2492: (p 0.4351345505)
436 TRACE t2492: => 0.9758465331678772
437 TRACE t2493: (p 0.9758465331678772)
438 TRACE t2493: => -0.7895631144708228
439 TRACE t2494: (p -0.7895631144708228)
440 TRACE t2494: => -0.39980345741334
445 ;; both space and number of steps grows as log3(a) -> log a to the base 3.
448 ;; a * (1/3)^n <= 0.1
449 ;; => take log to the base 3 on both the sides.
451 ;; Note: Finding the order of space in a recursive process is sort of, equiv
452 ;; to finding the number of deferred operations. Which is in-turn the
453 ;; same as the depth of the evaluation tree.
455 ;; 1.2.4: exponentiation
460 (* b (expt b (dec n)))))
466 (defn expt-iter [base counter product]
474 (defn fast-expt [b n]
476 (even? n) (square (fast-expt b (/ n 2)))
477 :else (* b (fast-expt b (dec n)))))
489 (defn expt-iter [b n a]
491 (even? n) (expt-iter (square b) (/ n 2) a)
492 :else (expt-iter b (- n 1) (* a b))))
498 (+ a (mult a (- b 1)))))
500 ;; product = 2 * (a * (b/2)) for even b
501 ;; = a + (a * (b - 1)) for odd b
502 (defn fast-mult [a b]
505 (even? b) (twice (fast-mult a (half b)))
506 :else (+ a (fast-mult a (- b 1)))))
515 ;; exercise 1.18: iterative multiply thru addition
516 ;; the idea is to keep a state variable.
517 (defn fast-mult-new [a b]
518 (fast-mult-iter a b 0))
520 (defn fast-mult-iter [a b k]
522 (even? b) (fast-mult-iter (twice a) (half b) k)
523 :else (fast-mult-iter a (- b 1) (+ k a))))
526 user> (dotrace [fast-mult-new fast-mult-iter] (fast-mult-new 2 3))
527 TRACE t2915: (fast-mult-new 2 3)
528 TRACE t2916: | (fast-mult-iter 2 3 0)
529 TRACE t2917: | | (fast-mult-iter 2 2 2)
530 TRACE t2918: | | | (fast-mult-iter 4 1 2)
531 TRACE t2919: | | | | (fast-mult-iter 4 0 6)
532 TRACE t2919: | | | | => 6
533 TRACE t2918: | | | => 6
534 TRACE t2917: | | => 6
540 ;; exercise 1.19: fast fibonacci
541 ;; see the pdf of the notebook scan for the derivation of p' and q'
543 (ffib-iter 1 0 0 1 n))
545 (defn ffib-iter [a b p q count]
551 (+ (* 2 p q) (* q q))
553 :else (ffib-iter (+ (* b q) (* a q) (* a p))