PageRenderTime 120ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/scheme/sicp/ch_3/chapter_03.scm

https://gitlab.com/o1s2/selflrrn
Scheme | 218 lines | 159 code | 41 blank | 18 comment | 0 complexity | fd612522f404afe2bb3e186e6f8bd499 MD5 | raw file
  1. ;;;; Various exercises from chapter 3
  2. ;;;;
  3. (load "lib.scm")
  4. ;;;; Exercise 3.1
  5. (define (make-accumulator initial-value)
  6. (lambda (n)
  7. (set! initial-value (+ initial-value n))
  8. initial-value))
  9. ;;;; Exercise 3.2
  10. (define make-monitored
  11. (let ((count 0))
  12. (lambda (fn)
  13. (lambda (x)
  14. (cond ((eq? x 'how-many-calls) count)
  15. ((eq? x 'reset) (set! count 0))
  16. (else
  17. (set! count (inc count))
  18. (fn x)))))))
  19. ;;;; Exercise 3.3
  20. (define (make-account acc-password balance)
  21. (let ((incorrect-password-attempts 0))
  22. (define %allowed-attempts 3)
  23. (define (withdraw amount)
  24. (if (>= balance amount)
  25. (begin (set! balance (- balance amount))
  26. balance)
  27. "Insufficient funds"))
  28. (define (deposit amount)
  29. (set! balance (+ balance amount))
  30. balance)
  31. (define (incorrect-password ignored-amount)
  32. (set! incorrect-password-attempts (inc incorrect-password-attempts))
  33. (if (>= incorrect-password-attempts %allowed-attempts)
  34. "Too many incorrect password attempts, please contact your local overlord"
  35. "Incorrect password"))
  36. (define (dispatch password message)
  37. (if (eq? password acc-password)
  38. (begin
  39. (set! incorrect-password-attempts 0)
  40. (cond ((eq? message 'withdraw) withdraw)
  41. ((eq? message 'deposit) deposit)
  42. (else (error "Unknown request -- MAKE-ACCOUNT" m))))
  43. incorrect-password))
  44. dispatch))
  45. ;;;; Exercise 3.6
  46. (define rand-max 1000)
  47. (define rand-init 0)
  48. (define rand
  49. (let ((x rand-init))
  50. (lambda (m)
  51. (cond ((eq? m 'generate)
  52. (let ((tmp x))
  53. (set! x (rand-update x))
  54. tmp))
  55. ((eq? m 'reset)
  56. (lambda (seed)
  57. (set! x seed)))
  58. (else (error "Unknown request -- RAND" m))))))
  59. ;; appropriately chosen integers
  60. (define a 1103515245)
  61. (define b 12345)
  62. (define m (expt 2 32))
  63. (define (rand-update x)
  64. (mod (+ (* a x) b)
  65. m))
  66. ;;;;
  67. (define (rng seed)
  68. "random number generator with seed"
  69. (let ((x seed))
  70. (lambda ()
  71. (let ((tmp x))
  72. (set! x (rand-update x))
  73. tmp))))
  74. ;;;; Exercise 3.7
  75. (define (make-account acc-password balance)
  76. (let ((incorrect-password-attempts 0) (passwords (list acc-password)))
  77. (define %allowed-attempts 3)
  78. (define (withdraw amount)
  79. (if (>= balance amount)
  80. (begin (set! balance (- balance amount))
  81. balance)
  82. "Insufficient funds"))
  83. (define (deposit amount)
  84. (set! balance (+ balance amount))
  85. balance)
  86. (define (incorrect-password ignored-amount)
  87. (set! incorrect-password-attempts (inc incorrect-password-attempts))
  88. (if (>= incorrect-password-attempts %allowed-attempts)
  89. "Too many incorrect password attempts, please contact your local overlord"
  90. "Incorrect password"))
  91. (define (add-password extra-password)
  92. (set-cdr! passwords (list extra-password)))
  93. (define (dispatch password message)
  94. (if (member? password passwords)
  95. (begin
  96. (set! incorrect-password-attempts 0)
  97. (cond ((eq? message 'withdraw) withdraw)
  98. ((eq? message 'deposit) deposit)
  99. ((eq? message 'add-password) add-password)
  100. (else (error "Unknown request -- MAKE-ACCOUNT" m))))
  101. incorrect-password))
  102. dispatch))
  103. (define (make-joint account acc-password extra-password)
  104. ((account acc-password 'add-password) extra-password)
  105. account)
  106. ;;;; Exercise 3.8
  107. (define f-global 0)
  108. (define (f n)
  109. (let ((tmp f-global))
  110. (set! f-global n)
  111. tmp))
  112. ;;;; Exercise 3.14
  113. (define (mystery x)
  114. (define (loop x y)
  115. (if (null? x)
  116. y
  117. (let ((temp (cdr x)))
  118. (set-cdr! x y)
  119. (loop temp x))))
  120. (loop x '()))
  121. ;;;; count number of pairs in an s-exp
  122. ; http://codereview.stackexchange.com/questions/2497/correctly-count-the-number-of-pairs-in-an-irregular-list-structure
  123. (define (count-pairs x)
  124. (define (iter x sum already-counted)
  125. (if (or (not (pair? x))
  126. (member x already-counted))
  127. (list sum already-counted)
  128. (let ((car-result (iter (car x) (+ sum 1) (cons x already-counted))))
  129. (iter (cdr x) (car car-result)
  130. (cadr car-result)))))
  131. (car (iter x 0 '())))
  132. ;;;; Exercise 3.18
  133. (define (cycle? x)
  134. (define (iter x already-seen)
  135. (cond ((null? x) #f)
  136. ((atom? (car x))
  137. (or (member? x already-seen)
  138. (iter (cdr x) (cons x already-seen))))
  139. (else
  140. (or (cycle? (car x))
  141. (cycle? (cdr x))))))
  142. (iter x '()))
  143. #!
  144. ;;; Exercise 3.50
  145. (define (stream-map proc . argstreams)
  146. (if ((stream-null? argstreams))
  147. the-empty-stream
  148. (cons-stream
  149. (apply proc (map stream-car argstreams))
  150. (apply stream-map (cons proc (map stream-cdr argstreams))))))
  151. !#
  152. ;;; Exercise 3.51
  153. (define (show x)
  154. (dnl x)
  155. x)
  156. (define (stream-enumerate-interval low high)
  157. (if (> low high)
  158. '()
  159. (stream-cons
  160. low
  161. (stream-enumerate-interval (inc low) high))))
  162. (define x (stream-map show (stream-enumerate-interval 1 10)))
  163. ;;;; Exercise 3.52
  164. (define sum 0)
  165. (define (accum x)
  166. (set! sum (+ x sum))
  167. sum)
  168. (define seq (stream-map accum (stream-enumerate-interval 1 20)))
  169. (define y (stream-filter even? seq))
  170. (define z (stream-filter (lambda (x) (= (remainder x 5) 0)) seq))
  171. ;;;; Exercise 3.59
  172. (define exp-series
  173. (cons-stream 1 (integrate-series exp-series)))
  174. (define cosine-series
  175. (cons-stream 1) (integrate-series (scale-stream sine-series -1)))
  176. (define sine-series
  177. (cons-stream 0 (integrate-series cosine-series)))