問題1.33

組み合せる項にフィルタ(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)の積

--

; --                                                                                                                            
; 標準的関数をロード                                                                                                            
; --                                                                                                                            
(load "./util.scm")

; --                                                                                                                            
; filter込みのaccumulate                                                                                                        
; --                                                                                                                            
(define (filtered-accumulate combiner null-value term a next b filter)
  (if (> a b)
      null-value
      (if (filter a)
          (combiner (term a) (filtered-accumulate combiner null-value term (next a) next b filter))
          (combiner null-value (filtered-accumulate combiner null-value term (next a) next b filter))
      )
  )
)

(print "計算結果: " (filtered-accumulate + 0 identity 1 inc 10 prime?))


このコードでaの問題を解決することができる。

$ gosh 1.33.scm
計算結果: 18


ただし、これではbの問題は解決できていない。gcdのように複数の引数を必要とするものはどう渡してよいのかわからない...。もう少し考えてみる。

amazon
『計算機プログラムの構造と解釈』