SICP 読み (5)
問題 1.33 が終わったら 1.3.2 節以降なんですが、数学なナニばっかりだなぁ。ま、コンピュータってのは基本的に「計算機」なんでそうなるのは仕方ないよなぁ。って今頃何言ってるんだろうか。(駄目
問題 1.33 (filterd-accumulate)
なかなか興味深い問題。filtered-accumulate はどちらが望ましいのだろうか。
その 1
(define (filtered-accumulate filter combiner null-value term a next b) (let f ((a a) (result null-value)) (if (filter (term a)) (if (> a b) result (f (next a) (combiner result (term a)))) (f (next a) result))))
その 2
(define (filtered-accumulate filter combiner null-value term a next b) (let f ((a a) (result null-value)) (if (> a b) result (f (next a) (if (filter a) (combiner result (term a)) result)))))
これは置き換えなナニで最適な方を選択するべきなんだろうか。正規順序だとその 1 はあり得んだろうな。
あら、よく見てみるとその 1 は filter にヒッカからなくて stack 突き破る可能性があるな。
その 3 (その 1 改)
(define (filtered-accumulate filter combiner null-value term a next b) (let f ((a a) (result null-value)) (if (> a b) result (if (filter (term a)) (f (next a) (combiner result (term a))) (f (next a) result)))))
うーん ... 微妙。
とりあえず、以下なナニでは動作している模様。
(define (aa a b) (filtered-accumulate (lambda (x) #t) (lambda (x y) (+ x y)) 0 (lambda (x) x) a (lambda (x) (+ x 1)) b))
試験なソレを書く癖も付けといた方が良いな。
guile> (define (test-aa) (eq? 55 (aa 1 10))) guile> (test-aa) #t guile>
TDD な道具が作れんかなぁ。ま、いいや。
a. については prime? 作るのが面倒なので上記 aa で OK としときます。一応ダミーな prime? で、な解を以下に。
(define (prime? x) #t) (define (aa a b) (filtered-accumulate prime? (lambda (x y) (+ x y)) 0 (lambda (x) x) a (lambda (x) (+ x 1)) b)) (define (test-aa) (eq? 55 (aa 1 10)))
次は b. です。
GCD なソレは 27p のものを流用。
(define (gcd a b) (if (= b 0) a (gcd b (remainder a b))))
条件は以下ですか。
- i は i < n な整数
- GCD(i, n) = 1
- 上記の条件を満たす数列の積
1 から 10 までで考えると 10 と素な数列の積は (* 1 3 7 9) なので試験な手続きを含めた一連の手続きは以下。
(define (gcd a b) (if (= b 0) a (gcd b (remainder a b)))) (define (bb a b) (filtered-accumulate (lambda (x) (eq? 1 (gcd b x))) (lambda (x y) (* x y)) 1 (lambda (x) x) a (lambda (x) (+ x 1)) b)) (define (test-bb) (eq? (* 1 3 7 9) (bb 1 10)))
試験を。
guile> (test-bb) #t guile>
なんか出力になーんの色気もないなぁ。
んーと、上記手続きは a < b 前提で作ってあるんですがセーフかなぁ。微妙だなぁ。