SICP 読み (98) 3.1.2 代入を取り入れた利点

kernel 方面からの現実トウヒ。がしかし、実行してません。理由は rand です。

問題 3.5

例示されている monte-carlo という手続きとその応用はとても面白い。問題 3.5 も数学オンチなわしにさえイメージできた。rand 手続きの実装ができてないので机上ベースなんですが、現時点でヒリ出しているのが以下の解。

(define (monte-carlo trials experiment)
  (define (iter trials-remaining trials-passed)
    (cond ((= trials-remaining 0)
	   (/ trials-passed trials))
	  ((experiment)
	   (iter (- trials-remaining 1) (+ trials-passed 1)))
	  (else
	   (iter (- trials-remaining 1) trials-passed))))
  (iter trials 0))

(define (random-in-range low high)
  (let ((range (- high low)))
    (+ low (random range))))

(define (estimate-integral p x1 x2 y1 y2 trials)
  (* (* (abs (- x1 x2)) (abs (- y1 y2)))
     (monte-carlo trials (lambda ()
			   (p (random-in-range x1 x2)
			      (random-in-range y1 y2))))))

(define (test-3.2)
  (define (square x) (* x x))
  (define (p x y)
    (<= (+ (square (- x 5)) (square (- y 7)) -9) 0))
  (let ((x1 2) (y1 4) (x2 8) (y2 10))
    (estimate-integral p x1 x2 y1 y2 1000)))

test-3.2 手続きは現時点では実行できん。test-3.2 の戻す値を 9 で割ったら円周率が出てくるはずなんですが、本当だろうか (を

問題 3.6

ええと、p.132 に例示されている rand 手続きを修正する形で検討してみる。以下が例示されているもの。

(define rand
  (let ((x random-init))
    (lambda ()
      (set! x (rand-update x))
      x)))

これを p.130 みたいな dispatch を使って 'generate とか 'reset でナニ。

(define (rand m)
  (let ((seed random-init))
    (cond ((eq? m 'generate) r-gen)
	  ((eq? m 'reset) r-reset)
	  (else
	   (error "Unkown request -- RAND" m)))

    (define (r-gen)
      (begin (set! seed (rand-update seed))
	     seed))

    (define (r-reset init)
      (begin (set! seed init)
	     'reset))))

うーん。微妙かも。