組み合せる項に フィルタ(filter)の考えを入れることで, accumulate(問題1.32)の更に一般的なものが得られる.
つまり範囲から得られて, 指定した条件を満した項だけを組み合せる.
出来上ったfiltered-accumulate抽象は, accumulate と同じ引数の他, フィルタを指定する一引数の述語をとる.
filtered-accumulateを手続きとして書け. filtered-accumulateを使い, 次をどう表現するかを示せ.
a. 区間a, bの素数の二乗の和(prime?述語は持っていると仮定する.)
b. nと互いに素で, nより小さい正の整数(つまりi < nでGCD(i, n)=1なる全整数i)の積
a. 区間a, bの素数の二乗の和(prime?述語は持っていると仮定する.)
b. nと互いに素で, nより小さい正の整数(つまりi < nでGCD(i, n)=1なる全整数i)の積
フィルターに対応したaccumulateを定義します.
考え方としては, filterが真を返すときはaccumulateと同様の処理をし,
偽を返すときはcombinerを使った計算をしないようにします.
手続きは次のようになります.
(require (lib "racket/trace.ss")) (define (inc x) (+ x 1)) (define (square x) (* x x)) (define (cube x) (* x x x)) (define (divides? a b) (= (remainder b a) 0)) (define (find-divisor n test-divisor) (cond ((> (square test-divisor) n) n) ((divides? test-divisor n) test-divisor) (else (find-divisor n (+ test-divisor 1))))) (define (smallest-divisor n) (find-divisor n 2)) (define (prime? n) (= n (smallest-divisor n))) ;; 再帰的プロセスを生成する. (define (filtered-accumulate-r filter combiner null-value term a next b) (cond ((> a b) null-value) ((filter a) (combiner (term a) (filtered-accumulate-r filter combiner null-value term (next a) next b))) (else (filtered-accumulate-r filter combiner null-value term (next a) next b)))) ;; 反復的プロセスを生成する. (define (filtered-accumulate-i filter combiner null-value term a next b) (define (iter a result) (cond ((> a b) result) ((filter a) (iter (next a) (combiner (term a) result))) (else (iter (next a) result)))) (iter a null-value)) ;; 区間a, bの素数の二乗の和 (define (sum-prime-square a b) (filtered-accumulate-r prime? + 0 square a inc b)) ;; nと互いに素で, nより小さい正の整数の積 (define (product-disjoint n) (define (disjoint? x) (= 1 (gcd n x))) (filtered-accumulate-r disjoint? * 1 identity 1 inc (- n 1)))
区間a, bの素数の二乗の和を求めてみます.
ようこそ DrRacket, バージョン 6.1 [3m]. 言語: Pretty Big; memory limit: 2048 MB. > (sum-prime-square 2 10) 87 > (+ (square 2) (square 3) (square 5) (square 7)) 87 >
2から10の間の素数は, 2, 3, 5, 7ですから, 計算は合っています.
nと互いに素で, nより小さい正の整数の積を求めてみます.
ようこそ DrRacket, バージョン 6.1 [3m]. 言語: Pretty Big; memory limit: 2048 MB. > (product-disjoint 10) 189 > (* 1 3 7 9) 189 >
10よりも小さい正の整数で10と互いに素になる数は, 1, 3, 7, 9ですから,
計算は合っています.
0 件のコメント:
コメントを投稿