1.3.1 引数としての手続き

素人くさい読書会に行けないので自習する。と決めてから早速やってなかった…。

前準備

(define (sum term a next b)
  (if (> a b)
    0
    (+ (term a)
       (sum term (next a) next b))))

(define (integral f a b dx)
  (define (add-dx x) (+ x dx))
  (* (sum f (+ a (/ dx 2.0)) add-dx b)
     dx))

(define (add1 x)
  (+ x 1))

(define (cube x)
  (* x x x))

(define (identity x) x)

1.29 Simpson公式(積分近似)

(define (integral-simpson f a b n)
  (define h (/ (- b a) n))
  (define (next x) (+ x h h))
  (define (f* x) (+ (* 2 (f x))
                    (* 4 (f (+ x h)))))
  (* (+ (f a)
        (* 4 (f (+ a h)))
        (sum f* (next a) next (- b h))
        (f b))
     (/ h 3)))

きたねー。後で他の人の解答見る。

1.30 反復的なsum

(define (sum term a next b)
  (define (iter a result)
    (if (> a b)
      result
      (iter (next a) (+ result (term a)))))
  (iter a 0))

1.31 与えられた範囲の数値の積を返すproduct, などなど

;; 再帰
(define (product f a next b)
  (if (> a b)
    1
    (* (f a) (product f (next a) next b))))

;; 反復
(define (product f a next b)
  (define (iter a result)
    (if (> a b)
      result
      (iter (next a) (* result (f a)))))
  (iter a 1))

(define (factorial n)
  (product identity 1 add1 n))

(define (pi-approx n)
  (define (add2 x) (+ x 2))
  (define (f t) (/ (* t (+ t 2))
                   (* (+ t 1) (+ t 1))))
  (* (product f 2 add2 n) 4))

1.32 accumulateで一般化

;; 再帰
(define (accumulate combiner null-value term a next b)
  (if (> a b)
    null-value
    (combiner (term a)
              (accumulate combiner null-value term (next a) next b))))

;; 反復
(define (accumulate combiner null-value term a next b)
  (define (accumulate-iter a result)
    (if (> a b)
      result
      (accumulate-iter (next a) (combiner result (term a)))))
  (accumulate-iter a null-value))

(define (sum/accumulate term a next b)
  (accumulate + 0 term a next b))

(define (product/accumulate term a next b)
  (accumulate * 1 term a next b))

きれいだ。

1.32 accumulateをフィルタ

(define (filtered-accumulate pred combiner null-value term a next b)
  (define (filtered-accumulate-iter a result)
    (cond 
      ((> a b)  result)
      ((pred a) (filtered-accumulate-iter (next a) (combiner result (term a))))
      (else     (filtered-accumulate-iter (next a) result))))
  (filtered-accumulate-iter a null-value))

(define (sum-of-prime-squares-between a b)
  (define (square x) (* x x))
  (filtered-accumulate prime? + 0 square a add1 b)) ; prime? : given

(define (product-of-coprimes n)
  (define (relatively-prime-to-n? x)
    (= (gcd x n) 1))
  (filtered-accumulate relatively-prime-to-n? * 1 identity 1 add1 n))