Created
November 17, 2020 02:05
-
-
Save timsneath/b2e3a914bd39d0408d0580c42ef2e58b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:math' show Random; | |
main() async { | |
print('Compute π using the Monte Carlo method.'); | |
await for (final estimate in computePi().take(100)) { | |
print('π ≅ $estimate'); | |
} | |
} | |
/// Generates a stream of increasingly accurate estimates of π. | |
Stream<double> computePi({int batch: 100000}) async* { | |
var total = 0; | |
var count = 0; | |
while (true) { | |
final points = generateRandom().take(batch); | |
final inside = points.where((p) => p.isInsideUnitCircle); | |
total += batch; | |
count += inside.length; | |
final ratio = count / total; | |
// Area of a circle is A = π⋅r², therefore π = A/r². | |
// So, when given random points with x ∈ <0,1>, | |
// y ∈ <0,1>, the ratio of those inside a unit circle | |
// should approach π / 4. Therefore, the value of π | |
// should be: | |
yield ratio * 4; | |
} | |
} | |
Iterable<Point> generateRandom([int? seed]) sync* { | |
final random = Random(seed); | |
while (true) { | |
yield Point(random.nextDouble(), random.nextDouble()); | |
} | |
} | |
class Point { | |
final double x, y; | |
const Point(this.x, this.y); | |
bool get isInsideUnitCircle => x * x + y * y <= 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment