(define (estimate-integral p x1 x2 y1 y2 times)
(let ((rect-area (* (- x2 x1) (- y2 y1)))
(ratio (monte-carlo times (lambda () (exp p x1 x2 y1 y2)))))
(* rect-area ratio)))
(define (exp p x1 x2 y1 y2)
(let ((random-x (random-in-range x1 x2))
(random-y (random-in-range y1 y2)))
(p (make-point random-x random-y))))
(define (in-circle? circle)
(lambda (point)
(let ((circle-x (caar circle))
(circle-y (cadar circle))
(radius (cadr circle))
(test-x (car point))
(test-y (cadr point)))
(<= (+ (square (- test-x circle-x)) (square (- test-y circle-y))) (square radius)))))
(define (make-circle center radius)
(list center radius))
(define (make-point x y)
(list x y))
(define (square x)
(* x x))
(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-pi)
(let ((radius 5.0)
(times 1000000)
(x 0)
(y 0))
(let ((circle (make-circle (make-point x y) radius)))
(let ((area (estimate-integral (in-circle? circle) -5 5 -5 5 times)))
(/ area (square radius))))))
(estimate-pi)