exercise 3.52

実家でだらだら過ごしすぎた・・・。
それはともかく、代入が絡むと色々面倒だと実感。
ちなみに以下の説明はほとんど殴り書き・・・。
というか、ちゃんと理解できてるのかな・・・


とりあえず、まずはメモ化してるバージョン。
問題にあるようにsumの値を追っかけていく。

(define sum 0)
;;sumは0
(define (accum x)
  (set! sum (+ x sum))
  sum)

(define seq
  (stream-map accum (stream-enumerate-interval 1 20)))
;;stream-mapが適用されるので、seqは
;;(cons 1 (delay (stream-map accum (stream-enumerate-interval 2 20))))
;;見たいな感じに。ちなみにsumは1
;;あと、seqの一番目はこれ以上accumの対象にならない

(define y (stream-filter even? seq))
;;sumは1でスタート
;;seqは(1 2 3 4...)であったが、accumが呼び出されていくので、
;;(1 3 6)とまで計算して、6が偶数なのでfilterに引っかかって計算終了。
;;ということでsumは6に
;;そんなこんなで
;;yはcarが6で、残りはseqの4番以降にfilterをかけたもの(という予定)
;;であってるかな・・・

(define z (stream-filter
           (lambda (x) (= (remainder x 5) 0))
           seq))
;;sumは6だったので、seqが
;;(1 3 6 4...)というのから
;;(1 3 6 (←ここまではメモ化されてるのでaccum の対象にならない) 10)
;;とまで計算されて、10が出るとfilterにかかるので、計算うち止め。ここでsumの値は10になる。
;;ちなみにseqは
;;(1 3 6 10)までメモ化されていて、残りは後で計算。

(stream-ref y 7)
;; -> 136
;;まずsumは10からはじまって、
;;yの方は(cons 6 (delay (filter even? (stream-map accum (stream-enumerate-interval 4 20)))))
;;見たいなかんじ(ここ不安・・・)
;;ちなみに6の次は(+ 4 sum)ではなく、10(メモ化されてるので)
;;ということで、filterをかける前のリストは
;;(6 10 ;(ここからaccum してく)
;;    15 21 28 ...)
;;filterかけると8番目が136になってる
;;そんなこんなでsumは136に。
;;あと、seqはそこまでメモ化される。

(display-stream z)
;;結果は
;;10                                                             
;;15                                                             
;;45                                                             
;;55                                                             
;;105                                                            
;;120                                                            
;;190                                                            
;;210done 
;;これ以上追うのはめんどすぎ・・・。無理


メモ化なっしんぐ。こっちはまだ追いかけやすい気がする。

(define sum 0)
;;sumは0
(define (accum x)
  (set! sum (+ x sum))
  sum)

(define seq
  (stream-map accum (stream-enumerate-interval 1 20)))
;;sumは1に。
;;seqの方は
;;(cons 1 (delay (stream-map accum (stream-enumerate-interval 2 20))))

(define y (stream-filter even? seq))
;;メモ化バージョンと同じく、sumは6に。
;;ただしseqはメモ化されていない!!。

(define z (stream-filter
           (lambda (x) (= (remainder x 5) 0))
           seq))
;;sumは15
;;メモ化されていないので、
;;seqはfilterかける前は
;;(1 2 3 4 5 ...)だったのが、accumされて
;;(1 8 11 15) みたいになる
;;一番目が1なのは上でも言ったけど、accumの対象外なので。。。
;;で、15まで計算したところで、filterにかかって、計算終わり。sumが15に。
;;zは(cons 15 (delay (stream-filter (lambda (x) (= (remaindr x 5) 0)) (stream-map accum (stream-enumerate-interval 5 20)))))
;;であってるかな・・・

(stream-ref y 7)
;;sumは15からスタート
;;yは一番目は6で、残りは4~20のリストにaccumをmapでして、filterかけたやつ(もはや日本語じゃない・・・)
:;(6 19 24 30...)
;;って感じで計算していくと、8番目の偶数が162になって、ここで計算止め。sumは162に

(display-stream z)
;;結果は
;;15                                                             
;;180                                                            
;;230                                                            
;;305done 
;;まぁあれだ、zは最初が15で残りは上で書いた奴。
;;ということでaccumしながらfilterかましてくと、こんな感じになりますよと。

あー、つかれた
なんという殴り書き。
まぁきっと将来自分が忘れた時に役立つでしょう。
しかしだいぶ時間かかったな・・・