SICP: Exercise 1.31
問題 1.31
sum
手続きは高階手続きとして書ける、同様な数多い抽象の最も単純なものに過ぎない。与えられた範囲の点での関数値の積を返すproduct
という似た手続きを書け。product
を使って、factorial
を定義せよ。また式 $$ \frac{\pi}{4} = \frac{2 \cdot 4 \cdot 4 \cdot 6 \cdot 6 \cdot 8 \cdots}{3 \cdot 3 \cdot 5 \cdot 5 \cdot 7 \cdot 7 \cdots} $$ によって \( \pi \) の近似値を計算するのにproduct
を使え。上の
product
が再帰的プロセスを生成するなら、反復的プロセスを生成するものを書け。反復的プロセスを生成するなら、再帰的プロセスを生成するものを書け。
a
和と同様に積 $$ \prod_{n = a}^b\,f(n) = f(a) \times \cdots \times f(b) $$ を表す手続きを書けばよい。
(define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b))))
階乗
階乗は sum-integers
と同様になる。
(define (factorial n) (product identity 1 inc n)) (factorial 0) ; 1 (factorial 1) ; 1 (factorial 5) ; 120 (factorial 10) ; 3628800
π の近似値
\( \pi \) の近似値は、初見時は一般項の表現に困ったが、 $$ \frac{2 \cdot 4}{3 \cdot 3} \cdot \frac{4 \cdot 6}{5 \cdot 5} \cdot \frac{6 \cdot 8}{7 \cdot 7} \cdots $$ と見たら分かりやすくなった。左上の数を \( k \) とおくと $$ \frac{k(k + 2)}{(k + 1)^2} $$ と表せる。このように表現したときは、\( k \) に 2 を加えて次の項を作る。
(define (pi-prod n) (define (pi-term x) (/ (* x (+ x 2.0)) (square (+ x 1)))) (define (pi-next x) (+ x 2)) (product pi-term 2 pi-next n))
実際に近似値を計算すると
(* 4 (pi-prod 10000000)) ; 少し時間がかかる ; 3.1415928106708866
3.141592 まで合った。
b
a の product
は再帰的プロセスなので反復的プロセスで書く。問題 1.30 と同様に書けばよい。
(define (product term a next b) (define (iter a result) (if (> a b) result (iter (next a) (* (term a) result)))) (iter a 1))