...
1import 'dart:async';
2import 'dart:html';
3import 'dart:math' show Random;
4
5// We changed 5 lines of code to make this sample nicer on
6// the web (so that the execution waits for animation frame,
7// the number gets updated in the DOM, and the program ends
8// after 500 iterations).
9
10main() async {
11 print('Compute π using the Monte Carlo method.');
12 var output = querySelector("#output");
13 await for (var estimate in computePi().take(500)) {
14 print('π ≅ $estimate');
15 output.text = estimate.toStringAsFixed(5);
16 await window.animationFrame;
17 }
18}
19
20/// Generates a stream of increasingly accurate estimates of π.
21Stream<double> computePi({int batch: 100000}) async* {
22 var total = 0;
23 var count = 0;
24 while (true) {
25 var points = generateRandom().take(batch);
26 var inside = points.where((p) => p.isInsideUnitCircle);
27 total += batch;
28 count += inside.length;
29 var ratio = count / total;
30 // Area of a circle is A = π⋅r², therefore π = A/r².
31 // So, when given random points with x ∈ <0,1>,
32 // y ∈ <0,1>, the ratio of those inside a unit circle
33 // should approach π / 4. Therefore, the value of π
34 // should be:
35 yield ratio * 4;
36 }
37}
38
39Iterable<Point> generateRandom([int seed]) sync* {
40 final random = new Random(seed);
41 while (true) {
42 yield new Point(random.nextDouble(), random.nextDouble());
43 }
44}
45
46class Point {
47 final double x, y;
48 const Point(this.x, this.y);
49 bool get isInsideUnitCircle => x * x + y * y <= 1;
50}
View as plain text