SICP 연습문제 1.31 친절한 풀이

문제

a. sum 프로시저는 차수 높은 프로시저로 간추릴 수 있는 보기 가운데 아주 단순한 것이다. sum과 비슷하게, 어떤 구간 속에 있는 점마다 정해진 함수의 값을 구하고 그 값을 모두 곱하는 프로시저 product를 짜보라. 그런 다음 아래 식을 파탕으로 ππ에 가까운 값을 얻어 보라.

π4=244668335577\frac{π}{4}=\frac{2⋅ 4 ⋅ 4 ⋅ 6 ⋅ 6 ⋅ 8 ⋯}{3 ⋅ 3 ⋅ 5 ⋅ 5⋅ 7⋅ 7⋯}

b. product의 프로세스가 되돈다면 반복하도록 고쳐쓰고, 그 반대로 반복한다면 되돌게끔 고쳐 보라.

문제로 부터 얻은 것

차수높은 프로시저를 사용하면, 수식을 표현하는 표현력을 극대화할 수 있습니다.

문제풀이

a. π값 찾기

이전 문제의 sum 프로시저를 참고해서 product 프로시저를 만들어 보겠습니다.
이전 문제에서는 result에 값을 더해서 축적했다면 이번에는 곱해서 축적하는것 밖에는 크게 달라진 것이 없습니다.
물론 초기값은 0이 아니라 1로 정해줘야 합니다.





sum 프로시저

(define (sum term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (+ result (term a)))))
(iter a 0))





product 프로시저

(define (product term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (* result (term a)))))
(iter a 1))





방금 만든 product로 ππ를 구해보겠습니다.
저는 아래의 식에서 f(n)f(n)을 반복의 기본 단위로 삼았습니다.

π4=244668335577\frac{π}{4}=\frac{2⋅ 4 ⋅ 4 ⋅ 6 ⋅ 6 ⋅ 8 ⋯}{3 ⋅ 3 ⋅ 5 ⋅ 5⋅ 7⋅ 7⋯}

π4=(2433)(4655)(6877)\frac{π}{4}=(\frac{2⋅ 4}{3 ⋅ 3}) ⋅ (\frac{4 ⋅ 6}{5 ⋅ 5}) ⋅ (\frac{6 ⋅ 8}{7⋅ 7}) ⋯

f(n)=(n1)(n+1)n2f(n) = \frac{(n-1)(n+1)}{n^2}

(define (pi-quarter n)
(define (f x)
(/ (* (- x 1.0) (+ x 1.0))
(square x)))
(define (next x)
(+ x 2.0))
(product f 3.0 next n))

(define (pi n)
(* (pi-quarter n)
4))

그리고 반복수를 10,000로 설정하고 ππ값을 구해보겠습니다.

(pi 10000)

π값을 얼추 구해내는 프로시저

b. 되도는 프로시저 만들기

반복하는 프로시저에서 되도는 프로시저를 만들어 보겠습니다.
result에 곱해서 인수로 넘겨주는 대신에, 곱셈 연산으로 묶어주면 쉽게 구현할 수 있습니다.

(define (product term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (* result (term a)))))
(iter a 1))

(define (product term a next b)
(if (> a b)
1
(* (product term (next a) next b)
(term a))))

읽어주셔서 감사합니다.