Advertisement
timothy235

sicp-1-2-4-exponentiation

Feb 16th, 2016
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 3.70 KB | None | 0 0
  1. #lang racket
  2.  
  3. ;; 1.16
  4.  
  5. ;; expt-iter is tail-recursive hence iterative
  6.  
  7. (define (iterative-fast-expt b n)
  8.   (define (expt-iter coeff base power)
  9.     ; the invariant is coeff * base ^ power = b ^ n
  10.     (cond [(zero? power) coeff]
  11.           [(even? power) (expt-iter coeff (sqr base) (/ power 2))]
  12.           [else (expt-iter (* base coeff) (sqr base) (/ (sub1 power) 2))]))
  13.   (expt-iter 1 b n))
  14.  
  15. (iterative-fast-expt 2 10)
  16. ;; 1024
  17. (iterative-fast-expt 3 5)
  18. ;; 243
  19. (time (iterative-fast-expt 2 1234))
  20. ;; cpu time: 0 real time: 0 gc time: 0
  21. ;; 295811224608098629060044695716103590786339687135372992239556207050657350796238
  22. ;; 924261053812082089933038176093702721248284094494136211066544377518349572681192
  23. ;; 920386118201521832389936024879031137085494026686245211006117942703402327660993
  24. ;; 170980488874938090231273982538640111837184
  25.  
  26. ;; 1.17
  27.  
  28. (define (double int) (* int 2))
  29. (define (halve even-int) (quotient even-int 2))
  30.  
  31. (define (fast-mult a b)
  32.   (cond [(= b 1) a]
  33.         [(even? b) (fast-mult (double a) (halve b))]
  34.         [else (+ a (fast-mult (double a) (halve (sub1 b))))]))
  35.  
  36. (fast-mult 2 3)
  37. ;; 6
  38. (fast-mult 3 4)
  39. ;; 12
  40. (time (fast-mult 987654321987654321 123456789123456789))
  41. ;; cpu time: 0 real time: 0 gc time: 0
  42. ;; 121932631356500531347203169112635269
  43.  
  44. ;; 1.18
  45.  
  46. ;; mult-iter is tail-recursive hence iterative
  47.  
  48. (define (iterative-fast-mult a b)
  49.   (define (mult-iter rem num1 num2)
  50.     ; the invariant is rem + num1 * num2 = a * b
  51.     (cond [(zero? num2) rem]
  52.           [(even? num2) (mult-iter rem (double num1) (halve num2))]
  53.           [else (mult-iter (+ rem num1) (double num1) (halve (sub1 num2)))]))
  54.   (mult-iter 0 a b))
  55.  
  56. (iterative-fast-mult 2 3)
  57. ;; 6
  58. (iterative-fast-mult 3 4)
  59. ;; 12
  60. (time (iterative-fast-mult 987654321987654321 123456789123456789))
  61. ;; cpu time: 0 real time: 1 gc time: 0
  62. ;; 121932631356500531347203169112635269
  63.  
  64. ;; 1.19
  65.  
  66. (define (exponential-fib n)
  67.   (if (< n 2)
  68.     n
  69.     (+ (exponential-fib (- n 1)) (exponential-fib (- n 2)))))
  70.  
  71. ;; The Fibonacci matrix is T(p, q) where p = 0 and q = 1.
  72.  
  73. ;; T(p, q) is [(p + q, q), (q, p)] and we want to pre-compute T(p, q) ^ 2 as
  74. ;; some T(p', q') in order to implement the iterative exponentiation process.
  75.  
  76. ;; T(p, q) ^ 2 = [((p + q) ^ 2 + q ^ 2, q * (p + q) + q * p),
  77.                ;; (q * (p + q) + q * p, p ^ 2 + q ^ 2)]
  78.             ;; = [(2 * q ^ 2 + 2 * p * q + p ^ 2, q ^ 2 + 2 * p * q),
  79.                ;; (q ^ 2 + 2 * p * q, q ^ 2 + p ^ 2)]
  80.  
  81. ;; So p' = q ^ 2 + p ^ 2 and q' = q ^ 2 + 2 * p * q.
  82.  
  83. (define (logarithmic-fib n)
  84.   (define (fib-iter a b p q cnt)
  85.     ; the invariant is (a, b) acted on by T(p, q) cnt times = (Fib(n + 1), Fib(n))
  86.     (cond [(zero? cnt) b]
  87.           [(even? cnt) (fib-iter a
  88.                                  b
  89.                                  (+ (sqr p) (sqr q))
  90.                                  (+ (sqr q) (* 2 p q))
  91.                                  (/ cnt 2))]
  92.           [else (fib-iter (+ (* b q) (* a q) (* a p))
  93.                           (+ (* b p) (* a q))
  94.                           p
  95.                           q
  96.                           (sub1 cnt))]))
  97.   (fib-iter 1 0 0 1 n))
  98.  
  99. (time (exponential-fib 30))
  100. ;; cpu time: 31 real time: 38 gc time: 0
  101. ;; 832040
  102. (time (logarithmic-fib 30))
  103. ;; cpu time: 0 real time: 0 gc time: 0
  104. ;; 832040
  105.  
  106.  
  107. (time (exponential-fib 40))
  108. ;; cpu time: 4594 real time: 4608 gc time: 0
  109. ;; 102334155
  110. (time (logarithmic-fib 40))
  111. ;; cpu time: 0 real time: 1 gc time: 0
  112. ;; 102334155
  113.  
  114. (time (logarithmic-fib 1000))
  115. ;; cpu time: 0 real time: 0 gc time: 0
  116. ;; 434665576869374564356885276750406258025646605173717804024817290895365554179490
  117. ;; 518904038775209689623239873322471161642996440906533187938298969649928516003704
  118. ;; 47613779516684922887
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement