SICPを読む(94) 問題 3.6 - 乱数発生器改
嗚呼、Schemeすることは難しい事じゃない。ただ脳に身を任せ・・・(謎
問題 3.6
乱数発生器を改造して、resetを付ける問題。
generateは要らないと思うので、無くした。
(define random-init 12345) (define (rand-update x) (modulo (+ (* 214013 x) 253011) 32767)) (define rand (let ((x random-init)) (lambda m (set! x (if (and (not (null? m)) (eq? (car m) 'reset)) (if (null? (cdr m)) random-init (cadr m)) (rand-update x))) x)))
テスト。
(rand) ; 10917 (rand) ; 18162 (rand 'reset) ; 12345 (rand) ; 10917 (rand) ; 18162 (rand 'reset 9876) ; 9876 (rand) ; 13462
こっちのほうが使いやすいと思う。
((rand 'reset) 10)
としたい場合は、(lambda (a) (set! x ...を返せばいい。
コードが見難いので、パターンマッチを使ってスッキリさせてみる。
(require (lib "match.ss")) (define rand (let ((x random-init)) (lambda m (set! x (match m (() (rand-update x)) ((reset) random-init) (`(reset ,a) a) (_ 'error))) x)))
引数がいっぱいあった時はかなり有効そうだ。