SICP - Solution: Exercise 1.33
October 26, 2018
Exercise 1.33 #
You can obtain an even more general version of accumulate (Exercise 1.32) by introducing the notion of a filter on the terms to be combined. That is, combine only those terms derived from values in the range that satisfy a specified condition. The resulting filtered-accumulate abstraction takes the same arguments as accumulate, together with an additional predicate of one argument that specifies the filter. Write filtered-accumulate as a procedure. Show how to express the following using filtered-accumulate:
- the sum of the squares of the prime numbers in the interval a to b (assuming that you have a prime? predicate already written)
- the product of all the positive integers less than n that are relatively prime to n (i.e., all positive integers i<n such that GCD(i,n)=1).
Solution #
filtered-accumulate
implementation
#
(define (filtered-accumulate predicate? combiner null-value term a next b)
(if (> a b)
null-value
(combiner
(if (predicate? a) (term a) null-value)
(filtered-accumulate predicate? combiner null-value term (next a) next b))))
sum of the squares of the prime numbers in the interval a to b #
(define (inc n) (+ n 1))
(define (sum-of-squares-prime a b)
(filtered-accumulate prime? + 0 square a inc b))
Product of all the positive integers less than n that are relatively prime to n #
The first step is defining the predicate to check for relative prime:
(define (relative-prime? i n)
(= (gcd i n) 1))
But predicate?
in filtered-accumulate
has only one argument. We need to specify the function inside product-of-relative-prime
so that we can get access to n
:
(define (identity x) x)
(define (product-of-relative-prime n)
(define (relative-prime? i)
(= (gcd i n) 1))
(filtered-accumulate relative-prime? * 1 identity 1 inc (- n 1)))