SICP問題3.81
乱数をresetする数値と、前の乱数の値からgenerateするための要求(今回はgenerateという文字列)からなるストリームを入力ストリームとして乱数のストリームを生成する手続き。
前の乱数の値から乱数を発生させるrand-updateはテスト用ですごく適当です。
(define (rand-stream s) (define random-init 1) ; 適当 (define (rand-update last-val) (+ last-val 1)) ; 超適当。ここは自分で考えたヤツで良いはず (define (rand-reset val) val) (define (req-result req last-val) (cond ((eq? req 'generate) (rand-update last-val)) ((number? req) (rand-reset req)) (else (error "Unknown request -- RAND" req)))) (define (rand-sub req-stream last-val) (let ((new-val (req-result (car req-stream) last-val))) (cons-stream new-val (rand-sub (stream-cdr req-stream) new-val)))) (rand-sub s random-init))
テスト用の入力ストリーム
(define test-list (list 'generate 5 'generate 'generate 10 14 2 3 5 'generate 'generate 'generate)) (define (make-test-stream org-list rest) (if (null? rest) (cons-stream (car org-list) (make-test-stream org-list (cdr org-list))) (cons-stream (car rest) (make-test-stream org-list (cdr rest))))) (define test-request (make-test-stream test-list test-list))
テスト
(stream-ref-range test-request 0 20) ; generate ; 5 ; generate ; generate ; 10 ; 14 ; 2 ; 3 ; 5 ; generate ; generate ; generate ; generate ; 5 ; generate ; generate ; 10 ; 14 ; 2 ; 3 ; #<undef> ; (stream-ref-range (rand-stream test-request) 0 20) ; 2 ; 5 ; 6 ; 7 ; 10 ; 14 ; 2 ; 3 ; 5 ; 6 ; 7 ; 8 ; 9 ; 5 ; 6 ; 7 ; 10 ; 14 ; 2 ; 3 ; #<undef>
rand-updateをどうにかすると、もう少しまともな感じになるかな。