/ch1.3.1.rkt

http://github.com/suguni/sicp · Racket · 230 lines · 131 code · 37 blank · 62 comment · 19 complexity · 2c8fe93c89ac7887521c1b2f0bf0e629 MD5 · raw file

  1. #lang racket
  2. ; 1.3.1 프로시저를 인자로 받는 프로시저
  3. ;; a ~ b 까지 정수 .
  4. (define (sum-integers a b)
  5. (if (> a b)
  6. 0
  7. (+ a (sum-integers (+ a 1) b))))
  8. ;; 정해진 넓이 정수를 모두 세제곱하여 더하기
  9. (define (cube x)
  10. (* x x x))
  11. (define (sum-cubes a b)
  12. (if (> a b)
  13. 0
  14. (+ (cube a) (sum-cubes (+ a 1) b))))
  15. ;; 1 / (1 * 3) + 1 / (5 * 7) + 1 / (9 * 11) + ...
  16. (define (pi-sum a b)
  17. (if (> a b)
  18. 0
  19. (+ (/ 1.0 (* a (+ a 2))) (pi-sum (+ a 4) b))))
  20. ;; SUM
  21. (define (sum term a next b)
  22. (if (> a b)
  23. 0
  24. (+ (term a) (sum term (next a) next b))))
  25. ;; sum-cubes의 sum 이용 버전
  26. (define (inc x) (+ x 1))
  27. (define (sum-cubes-2 a b)
  28. (sum cube a inc b))
  29. ;; sum-integers의 sum 이용 버전
  30. (define (identify x) x)
  31. (define (sum-integers-2 a b)
  32. (sum identify a inc b))
  33. ;; pi-sum의 sum 이용 버전
  34. (define (pi-sum-2 a b)
  35. (define (term x)
  36. (/ 1.0 (* x (+ x 2))))
  37. (define (next x)
  38. (+ x 4))
  39. (sum term a next b))
  40. ;; integral
  41. (define (integral f a b dx)
  42. (define (next x)
  43. (+ x dx))
  44. (* (sum f (+ a (/ dx 2.0)) next b) dx))
  45. ;; ex 1.29
  46. ;; Simpson's rule, http://en.wikipedia.org/wiki/Simpson%27s_rule
  47. ;;
  48. ;; Simpson's rule은 f(x)를 a~b로 정적분하는 규칙으로,
  49. ;; a, (a+b)/2, b의 3점을 지나는 Lagrange polynomial interpolation(2 방정식) 하고, 이를 적분한 식으로부터 면적을 계산한다.
  50. ;; f(x) a~b 구간은 2 방정식으로 interpolation한 함수를 P(x)라고 하고, a와 b의 중간점((a+b)/2) m이라 하면,
  51. ;; P(x) a~b 구간에서 적분값은 ((b - a) / 6) * (f(a) + 4f(m) + f(b)) 이다.
  52. ;;
  53. ;; f(x) A~B 구간을 짝수인 n 구간(h=(B-A)/n)으로 나누고(나눈 위치를 x0(=A), x1, x2, ... xn(=B) 이라고 하고), 2 구간씩을 Simpson's rule에 따라 계산하면
  54. ;; 정적분 값은 h/3 * (f(x0) + 4*f(x1) + 2*f(x2) + 4*f(x3) + 2*f(x4) + ... + 4*f(xn-1) + f(xn)) 되고 이를 SUM으로 표현하면,
  55. ;; h/3 * (f(x0) + 4*SUM(f(x2i-1)) + 2*SUM(f(x2)) + f(n)) 된다.
  56. ;;
  57. ;; 아래 2가지 방법의 결과가 틀리다.
  58. ;; 이건 a부터 시작해서 h만큼 늘어가는 방법
  59. (define (integral-simpson f a b n)
  60. (define h (/ (- b a) n))
  61. (define (term x) ; x = a + kh
  62. (* (cond ((or (= x a) (= x b)) 1)
  63. ((odd? (/ (- x a) h)) 4)
  64. (else 2))
  65. (f x)))
  66. (define (next x)
  67. (+ x h))
  68. (* (/ h 3.0) (sum term a next b)))
  69. ;; (integral-simpson cube 0 10 100) => 2500.0
  70. ;; 이건 n만큼 돌린다고 생각하고 짠것.
  71. (define (integral-simpson-2 f a b n)
  72. (define h (/ (- b a) n))
  73. (define (term x)
  74. (* (cond ((or (= x 0) (= x n)) 1)
  75. ((odd? x) 4)
  76. (else 2))
  77. (f (+ a (* x h)))))
  78. (* (/ h 3.0) (sum term 0 inc n)))
  79. ;; (integral-simpson-2 cube 0 10 100) => 2500.0
  80. ;; ex 1.30
  81. ;; recursive process SUM
  82. ;(define (sum term a next b)
  83. ; (if (> a b)
  84. ; 0
  85. ; (+ (term a) (sum term (next a) next b))))
  86. ;; iterative process SUM 짜기
  87. (define (sum-i term a next b)
  88. (define (iter x result)
  89. (if (> x b)
  90. result
  91. (iter (next x) (+ result (term x)))))
  92. (iter a 0))
  93. ;; iterative process sum 테스트
  94. (define (sum-cubes-i a b)
  95. (sum-i cube a inc b))
  96. ;; ex 1.31
  97. ;; product를 차수높은 프로시저로 짜기
  98. ;; a - recursive process
  99. (define (product-r term a next b)
  100. (if (> a b)
  101. 1
  102. (* (term a) (product-r term (next a) next b))))
  103. ;; (product-r identify 1 inc 10) => 3628800
  104. ;; b - iterative process
  105. (define (product-i term a next b)
  106. (define (iter x result)
  107. (if (> x b)
  108. result
  109. (iter (next x) (* result (term x)))))
  110. (iter a 1))
  111. ;; (product-i identify 1 inc 10) => 3628800
  112. ;; c - pi/4 계산하기
  113. ;; pi/4 = (2/3)*(4/3)*(4/5)*(6/5)*(6/7)*...
  114. ;; 분자는 2 4 4 6 6 8 8 ...
  115. ;; i가 홀수면 i+1, 짝수면 i+2
  116. ;; 분모는 3 3 5 5 7 7 9 9 ...
  117. ;; i가 홀수면 i+2, 짝수면 i+1
  118. (define (pi-over-4 n)
  119. (define (term a)
  120. (/ (if (odd? a) (+ a 1.0) (+ a 2))
  121. (if (odd? a) (+ a 2.0) (+ a 1))))
  122. (product-i term 1 inc n))
  123. ;; (pi-over-4 1000000) => 0.7853985560957135
  124. ;; (/ pi 4) => 0.7853981633974483
  125. ;; ex 1.32
  126. ;; accumulate 짜기
  127. (define (accumulate-r combiner null-value term a next b)
  128. (if (> a b)
  129. null-value
  130. (combiner (term a) (accumulate-r combiner null-value term (next a) next b))))
  131. (define (accumulate-i combiner null-value term a next b)
  132. (define (iter x result)
  133. (if (> x b)
  134. result
  135. (iter (next x) (combiner result (term x)))))
  136. (iter a null-value))
  137. (define (product-a-r term a next b)
  138. (accumulate-r * 1 term a next b))
  139. ;; (product-a-r identify 1 inc 10) => 3628800
  140. (define (product-a-i term a next b)
  141. (accumulate-i * 1 term a next b))
  142. ;; (product-a-i identify 1 inc 10) => 3628800
  143. (define (sum-a-r term a next b)
  144. (accumulate-r + 0 term a next b))
  145. ;; (sum-a-r identify 0 inc 10) => 55
  146. (define (sum-a-i term a next b)
  147. (accumulate-i + 0 term a next b))
  148. ;; (sum-a-i identify 0 inc 10) => 55
  149. ;; ex 1.33
  150. ;; filtered-accumulate 짜고 책에 있는 a, b 짜기
  151. (define (filtered-accumulate-r combiner null-value filter term a next b)
  152. (if (> a b)
  153. null-value
  154. (combiner (if (filter a)
  155. (term a)
  156. null-value)
  157. (filtered-accumulate-r combiner null-value filter term (next a) next b))))
  158. (define (filtered-accumulate-i combiner null-value filter term a next b)
  159. (define (iter x result)
  160. (if (> x b)
  161. result
  162. (iter (next x) (combiner result (if (filter x) (term x) null-value)))))
  163. (iter a null-value))
  164. ;(filtered-accumulate-r + 0 even? identify 0 inc 10) ; => 30
  165. ;(filtered-accumulate-r + 0 odd? identify 0 inc 10) ; => 25
  166. ;(filtered-accumulate-i + 0 even? identify 0 inc 10) ; => 30
  167. ;(filtered-accumulate-i + 0 odd? identify 0 inc 10) ; => 25
  168. (define (square x)
  169. (* x x))
  170. (define (prime? n)
  171. (= (smallest-divisor n) n))
  172. (define (smallest-divisor n)
  173. (define (divides? a b)
  174. (= (remainder a b) 0))
  175. (define (square x)
  176. (* x x))
  177. (define (find-divisor value test-div)
  178. (cond ((divides? value test-div) test-div)
  179. ((> (square test-div) value) value)
  180. (else (find-divisor value (+ test-div 1)))))
  181. (find-divisor n 2))
  182. (define (sum-prime-square a b)
  183. (filtered-accumulate-i + 0 prime? square a inc b))
  184. ;; (sum-prime-square 2 10) => 2*2 + 3*3 + 5*5 + 7*7 = 87
  185. (define (GCD a b)
  186. (if (= b 0)
  187. a
  188. (GCD b (remainder a b))))
  189. (define (product-seed n)
  190. (define (filter x)
  191. (= (GCD x n) 1))
  192. (filtered-accumulate-i * 1 filter identify 1 inc (- n 1)))
  193. ;; (product-seed 10) ;; => (* 1 3 7 9) = 189