Exercise 3.56. - 3.58.

Exercise 3.56

Exercise 3.56.

(define S (cons-stream 1 (merge (merge (scale-stream S 2) (scale-stream S 3)) (scale-stream S 5))))

で良いはずなんだけど手元の gosh 0.8.11 では merge がうまく動いてくれなくて無限ループになった。

Exercise 3.57

Exercise 3.57.

メモ化なしの場合、フィボナッチ数列のストリームの各要素を求めるのに加算が何回必要かという問題。

(define fibs
  (cons-stream 0
               (cons-stream 1
                            (add-streams (stream-cdr fibs)
                                         fibs))))

まずは具体的に考えていくしかないわな。

  • 最初の 0 と 1 の 2 項は既知なので足し算の数は 0 回。
  • 第 3 項は既知の第 1 項、第 2 項の和 0 + 1 = 1 で求まるから足し算は 1 回。
  • 第 4 項は第 2 項、第 3 項の和 1 + 1 = 2 だけど、第 2 項を求めるのに足し算は 0 回必要。第 3 項を求めるのに足し算は 1 回必要。最後にその 2 つを足すの 1 回必要。よって計 2 回必要となる。

以上から n > 3 のとき、第 n 項の足し算の回数は {第 (n-2) 項の回数} + {第 (n-1) 項の回数} + 1 で良いはず。ちなみにメモ化してたらどの項も足し算は 1 回で済む。

Exercise 3.58

Exercise 3.58.

(define (expand num den radix)
  (cons-stream
   (quotient (* num radix) den)
   (expand (remainder (* num radix) den) den radix)))

これが何をする関数かと言う問題。見ただけでは分からなかったので、実際に紙と鉛筆で (expand 1 7 10) と (expand 3 8 10) を解いてみた。

そうしたらすぐに分かった。expand は radix 進数のときの有理数 num/dev を少数で表現したときのの各桁の数字がストリームになって求まるというモノ。

project euler循環小数の問題があったはずなので、これは使えるはず。しめしめ。

今日はここまで

最初に読んだときは何で飛ばしたんだろうと思うぐらいにストリームがおもしろい。でも結構必死w。当初の目論見通りに project euler の方へ還元できればいいけど。