#lang racket (require "3-5-streams.rkt") ;;;;;;;;;; ;; 3.81 ;; ;;;;;;;;;; (define (make-prng seed) (define (rand-update x) (remainder (+ 11 (* 23 x)) 493)) (define (random-stream request-stream x0) (define m0 (stream-car request-stream)) (define x1 (cond [(eq? m0 'generate) (rand-update x0)] [(eq? m0 'reset) seed] [else (error "Unknown request -- PRNG:" m0)])) (cons-stream x0 (random-stream (stream-cdr request-stream) x1))) (lambda (ms) (random-stream ms seed))) ;; TEST (define example-request-stream ; Reset every fourth request. (my-stream-map (lambda (x) (if (zero? (remainder x 4)) 'reset 'generate)) integers)) (define rand-stream ((make-prng 10) example-request-stream)) (display-this-many 10 rand-stream) ;; 10 241 131 66 10 241 131 66 10 241 ;; 'done ;;;;;;;;;; ;; 3.82 ;; ;;;;;;;;;; (define (monte-carlo experiment-stream passed failed) (define (next passed failed) (cons-stream (exact->inexact (/ passed (+ passed failed))) (monte-carlo (stream-cdr experiment-stream) passed failed))) (if (stream-car experiment-stream) (next (add1 passed) failed) (next passed (add1 failed)))) (define (inexact-random low high) (+ low (* (random) (- high low)))) (define (estimate-integral predicate x1 x2 y1 y2) (define (rand-update . args) ; Produce a random pair in the right ranges when applied to any argument. (list (inexact-random x1 x2) (inexact-random y1 y2))) (define area (* (- x2 x1) (- y2 y1))) (define random-pairs (cons-stream (rand-update) (my-stream-map rand-update random-pairs))) (define experiment-stream (my-stream-map (lambda (pr) (apply predicate pr)) random-pairs)) (scale-stream (monte-carlo experiment-stream 0 0) area)) (define (in-unit-circle? x y) (< (+ (sqr x) (sqr y)) 1)) (define pi-stream (estimate-integral in-unit-circle? -1 1 -1 1)) (my-stream-ref pi-stream 100) ;; 3.00990099009901 (my-stream-ref pi-stream 1000) ;; 3.1888111888111887 (my-stream-ref pi-stream 10000) ;; 3.1632836716328367 (my-stream-ref pi-stream 100000) ;; 3.153968460315397 (my-stream-ref pi-stream 1000000) ;; 3.1423408576591423