q3.5/q3.6

;;q3.5
;;そんなわたしはMzScheme派
(require (lib "27.ss" "srfi"))
(define (square x) (* x x))
(define random random-real)
(define (random-in-range low high)
 (let ((range (- high low)))
   (+ low (* (random) range))))
(define (monte-carlo trails experiment)
 (define (iter trails-remainding trails-passed)
   (cond ((= trails-remainding 0)
          (/ trails-passed trails))
         ((experiment) ;;run experiment with no args
          (iter (- trails-remainding 1) (+ trails-passed 1)))
         (else
           (iter (- trails-remainding 1) trails-passed))))
 (iter trails 0))
;;中心とか半径とか調べるのが面倒なので全部正の時のみ許すことにした。
(define (estimate-integral p x1 x2 y1 y2 trails)
 (if (or (<= x1 0) (<= x2 0) (<= y1 0) (<= y2 0) (< trails 0))
     (error "can't process. every arg must be plus")
     (* (* (- x2 x1) (- y2 y1))
        (monte-carlo trails (lambda () (p
                                   (random-in-range x1 x2)
                                   (random-in-range x1 x2)
                                   (- (/ (+ x1 x2) 2) x1)
                                   (/ (+ x1 x2) 2)
                                   (/ (+ y1 y2) 2)
                                  ))))
  ))
(estimate-integral
 (lambda (x y r x0 y0)
 (<= (+ (* (- x x0) (- x x0)) (* (- y y0) (- y y0))) (* r r)))
 1 3 1 3 100000.0)

;;いまだにlambdaがわからん。
;;((experiment) ;;run experiment with no args
;;でこまった。
;;5引数だけどmonte-carlo内では0引数で呼ばれるので渡すときに0引
;;数に仕立てないとだめっていうのが。かーりー?わかんね。
(define (p x y) (< x y))
(define (proc hoge fuga)
   (newline) (display hoge) ;=>#<procedure>
   (newline)(display (hoge)) ;;引数0個で実行される
   (newline)(display (fuga 3 2)) ;;引数2個で実行される
   (newline)
 )
;(proc (p 1 2) p) ;もちろんだめ
;> procedure application: expected procedure, given: #t (no arguments)
;渡す時にすでに#tに評価されてるので「手続きよこせや!」としかられた。
(proc (lambda () (p 1 2)) p)


;;q3.6
;;ref http://d.hatena.ne.jp/keyword/%C0%FE%B7%C1%B9%E7%C6%B1%CB%A1
(define (rand)
  (define newvalue 0)
  (define (generate)
    (set! newvalue
          (modulo (+ (* newvalue 1664525) 1013904223) 4294967296))
    newvalue)
  (define (reset y)
    (set! newvalue y)
    newvalue)
  (define (dispatch m)
    (cond
        ((eq? m 'generate) generate)
        ((eq? m 'reset) reset)
        (else (error "can not dispatch!"))
     )
    )
  dispatch)
(define r (rand))
((r 'reset) 3)
((r 'generate ))
;> 3
;> 1018897798
;> 2365144877
;> 3752335016
;> 3345418727
;> 1647017498
;> 3
;> 1018897798
;> 2365144877
;> 3752335016
;> 3345418727
;> 1647017498
;> 3714889393
;> 2735194204
;同じ種で同じ数値で