SICP 読み (128) 3.5.1 ストリームは遅延リスト
問題 3.52
複数の課題が提示されている。時間かかりそ。
まず sum の値と応答印字から。なるべく脳内変換を心掛けたいですが、控えも残す方向でやってみます。まず、以下に提示されている一連の式を。
gosh> (define sum 0) sum gosh> (define (accum x) (set! sum (+ x sum)) sum) accum gosh> (define seq (stream-map accum (stream-enumerate-interval 1 20))) seq gosh> (define y (stream-filter even? seq)) y gosh> (define z (stream-filter (lambda (x) (= (remainder x 5) 0)) seq)) z gosh>
で、
(stream-ref y 7) (display-stream z)
まで終了した時点での上記のナニ。とりあえず seq が define された時点で seq が束縛されるのは
(cons 1 (delay (stream-map accum (stream-cdr (cons 1 (stream-enumerate-interval 2 20))))))
になりますな。ハズしてるかもしれんが長いし面倒なんでこう書く。
(cons 1 (delay (stream-map accum (force (delay (stream-enumerate-interval 2 20))))))
微妙。ちなみにこの時点でスデに accum の値は 1。
次
どんどん行く。y が define された時点で束縛されているのは以下の式。
(cons 2 (delay (stream-filter even? (force (delay (stream-map accum (force (delay (stream-enumerate-interval 3 20)))))))))
わははは。ワケワカ。ちなみに sum の値は 3。
# 断言しちゃって良いのだろうか。
次
次は z の define ですな。5 で割り切れるか、という事なんで z には以下のリストが束縛される、と見ました。
(cons 5 (delay (stream-filter (lambda (x) (= (remainder x 5) 0)) (force (delay (stream-map accum (force (delay (stream-enumerate-interval 6 20)))))))))
で、sum の値は 15 になっているはず。
その次
stream-ref は C の配列なインデクスと同じ考え方なんで引数 7 なら 8 番目。なので stream-ref が戻すのは 16 になるはず。この時点での sum の値は 136 と見た。
次の display-stream が戻すのは
(5 10 15 20)
かなぁ。で、sum の値は 210 になる、と。
検証
gosh で試験してみたらこんなになった。何故だ。
gosh> (define sum 0) sum gosh> (define (accum x) (set! sum (+ sum x)) sum) accum gosh> (define seq (stream-map accum (stream-enumerate-interval 1 20))) seq gosh> sum 1 gosh> (define y (stream-filter even? seq)) y gosh> sum 6 gosh> y (6 . #<closure (memo-proc memo-proc)>) gosh>
なんか stream-map とか stream-filter を勘違いしてるのかなぁ。あ、分かった。accum された値が、なのか。とほほほ。
再検討
gosh> (define sum 0) sum gosh> (define (accum x) (set! sum (+ x sum)) sum) accum gosh> (define seq (stream-map accum (stream-enumerate-interval 1 20))) seq
まず、ここでは sum は 1 で seq は (1 . #
gosh> seq (1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210) gosh> y (6 10 28 36 66 78 120 136 190 210) gosh> z (10 15 45 55 105 120 190 210) gosh>
とほほほ。てコトは
gosh> (define y (stream-filter even? seq)) y
な時点では、sum は 6 (+ 1 2 3) で y は (6 . #
gosh> (define z (stream-filter (lambda (x) (= (remainder x 5) 0)) seq)) z gosh>
な時点では、sum は 10 (+ 1 2 3 4) で z は (10 . #
上記のリストから言えば (stream-ref y 7) は 136 が戻るか。あるいは (display-stream z) は上記のソレが出てくるという事になる。
それにしても馬鹿丸出しなんですが、このままエントリ投入。続きは別途。