Given:

(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))))

The solution is:

(define (P x y) (< (+ (expt (- x 5) 2) (expt (- y 7) 2)) (expt 3 2))) (define (estimate-integral P x1 x2 y1 y2 trials) (define (experiment) (P (random-in-range x1 x2) (random-in-range y1 y2))) (monte-carlo trials experiment))

Test:

```
(estimate-integral P 2.0 8.0 4.0 10.0 100)
```

Then we can estimate pi with the fact that a circle area is (pi * r²).

Hence pi ≅ (Monte Carlo results * rectangle area) / r²

```
(define pi-approx
(/ (* (estimate-integral P 2.0 8.0 4.0 10.0 10000) 36)
9.0))
pi-approx
```

Which gave 3.1336 during my test.

This function has to be tested under MIT Scheme, neither gambit-scheme or SISC implements (random) - actually (random) is not part of R5RS nor SRFI.

NB: using 2.0 instead of 2 in estimate-integral is primordial. If you pass two integers to (random-in-range low high), it will return another integer strictly inferior to your 'high' value — and this completely screws the Monte-Carlo method (it then estimates pi to ~3.00).

<< Previous exercise (3.4) | Index | Next exercise (3.6) >>

If you're using Racket the random function doesn't work as described in the text. You might want to use this instead:

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