問題1.33

僕の解答

フィルタの説明が少ないよ…。
filtered-accumulateがこんな感じかな?

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

(define (filtered-accumulate combiner null-value term a next b filter)
	(define (filtering a)
		(if (filter a) (term a) null-value))
	(define (iter a result)
		(if (> a b)
		    result
		  (iter (next a)
			(combiner result (filtering a)))))
	(iter a null-value))

(define (sum term a next b filter)
	(filtered-accumulate + 0 term a next b filter))

(define (sum-even a b)
	(sum (lambda (x) x) a (lambda (x) (+ x 1)) b even?))

(define (product term a next b filter)
	(filtered-accumulate * 1 term a next b filter))

(define (product-even a b)
	(product (lambda (x) x) a (lambda (x) (+ x 1)) b even?))

(display (sum-even 1 10))
(newline)
(display (product-even 1 5))
(newline)
a.
(define (smallest-divisor n)
	(find-divisor n 2))

(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 (divides? a b)
	(= (remainder b a) 0))

(define (prime? n)
	(and (> n 1)
	     (= n (smallest-divisor n))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (square n)
	(* n n))

(define (inc n)
	(+ n 1))

(define (filtered-accumulate combiner null-value term a next b filter)
	(define (filtering a)
		(if (filter a) (term a) null-value))
	(define (iter a result)
		(if (> a b)
		    result
		  (iter (next a)
			(combiner result (filtering a)))))
	(iter a null-value))

(define (sum-prime-square a b)
	(filtered-accumulate + 0 square a inc b prime?))

(display (sum-prime-square 1 10))
(newline)

b.

(define (gcd a b)
	(if (= b 0)
	    a
	  (gcd b (remainder a b))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (filtered-accumulate combiner null-value term a next b filter)
	(define (filtering a)
		(if (filter a) (term a) null-value))
	(define (iter a result)
		(if (> a b)
		    result
		  (iter (next a)
			(combiner result (filtering a)))))
	(iter a null-value))

(define (identity n) n)

(define (inc n)
	(+ n 1))

(define (func-x n)
	(define (filter x)
		(= (gcd x n) 1))
	(filtered-accumulate * 1 identity 1 inc (- n 1) filter))

(display (func-x 10))
(newline)

合ってるかな…

所感

フィルタに引っかかったら、計算すっ飛ばすんじゃなくて、null-valueで計算はやっぱまずいか。
修正しよう。

(define (filtered-accumulate combiner null-value term a next b filter)
	(define (filtering a)
		(if (filter a) (term a) null-value))
	(cond ((> a b) null-value)
	      ((filter a)
	       (combiner (filtering a)
			 (filtered-accumulate combiner null-value term (next a) next b filter)))
	      (else
	       (filtered-accumulate combiner null-value term (next a) next b filter))))