Some answers are painful to calculate with a formula. But running the same random experiment ten thousand times? That's just a loop with a counter. That's the entire trick behind Monte Carlo simulation — and you already know how to write it.
Picture a jar of jellybeans. You could count every bean by hand — slow and error-prone. Or you could grab handfuls at random, look at what you got, and after enough handfuls you'd know the jar pretty well. Monte Carlo is the second approach, turned into code: model the situation, feed it random inputs, run it a huge number of times, and read the answer off the results.
Instead of deriving a clean equation, you let random chance explore the problem for you — one possible outcome at a time.
One random trial tells you almost nothing. A million of them, averaged together, tells you almost everything.
Its real superpower: it hands you a whole range of possible outcomes and how likely each one is — not a single fragile guess.
Here's the famous one. Draw a square, and inside it a quarter-circle. Now throw darts at the square completely at random. The darts that land inside the curve, compared to the total, are directly linked to π. No circle formula required at the throwing stage — just a coin-toss of geometry and a tally.
Notice how jumpy the estimate is with just a handful of darts — and how it steadies as the count climbs. That's the whole point of the next section.
The square has area 1. The quarter-circle inside it has area π/4. Throw darts evenly across the square and the fraction that land inside the curve will hover around π/4. Flip that around and you get your estimate:
π ≈ 4 × (inside ÷ total)
A dart is "inside" when its distance from the corner is ≤ 1 — i.e. x² + y² ≤ 1. That single check is the only geometry you need.
// The entire simulation. Yes, really. let inside = 0; const N = 1_000_000; for (let i = 0; i < N; i++) { const x = Math.random(); // 0 … 1 const y = Math.random(); // 0 … 1 if (x*x + y*y <= 1) inside++; } const pi = 4 * inside / N; console.log(pi); // ≈ 3.14159…
There's one law doing all the work here, and it has an intimidating name — the Law of Large Numbers — for a simple idea: the more times you repeat a random experiment, the closer your average result lands to the truth. Watch the estimate stagger around early on, then lock onto π.
Accuracy improves, but slowly. To get one extra digit of precision, you roughly need 100× more trials. That trade-off — easy to set up, expensive to make razor-sharp — is the defining personality of Monte Carlo. It's why it shines for "good enough" answers to messy problems, and struggles when you need many decimal places.
Think of each trial as a noisy vote. A few votes can swing wildly. But as votes pile up, the random over- and under-shoots cancel out, and the signal underneath rises to the surface. You're not making any single trial more accurate — you're drowning the randomness in volume.
Strip away the π example and what's left is a recipe that works for almost any uncertain system. Once you see the shape of it, you'll spot Monte Carlo problems everywhere.
function monteCarlo(runs) { const results = []; for (let i = 0; i < runs; i++) { const outcome = simulateOneTrial(); // steps 1 & 2 results.push(outcome); // step 3 } return summarise(results); // step 4: avg, %, histogram… }
π is cute, but here's where Monte Carlo earns its keep. You've got five chunks of work, each with a best case, likely case, and worst case. Adding up the "likely" numbers gives one tidy estimate — and it lies to you, because work rarely all goes to plan at once. Instead, simulate the whole project thousands of times with random task durations and look at the spread of outcomes.
Each bar = how often, out of all the simulated projects, the total landed in that range of days. The red line is your deadline.
Drag the deadline after running — the odds update instantly off the same simulated outcomes.
The naïve "add up the likely numbers" answer is 29 days. Run the simulation and you'll usually find the odds of actually hitting that are uncomfortably low. That gap is risk you couldn't see — and the reason people reach for Monte Carlo.
If you can simulate one outcome, you can estimate anything.
Loop it. Count it. Average it. You walked in knowing how to write a loop and a counter — and that was always the hard part. The rest is just letting randomness do the exploring while repetition sharpens the answer.