I remember being amazed years ago when I first read about Buffon’s Needle problem. You can estimate the value of pi (~3.1416) by dropping a needle on a floor made from wooden slats, and counting how many times the needle crosses the edge of a slat. Remarkable.

If the wood slats are w wide, and the needle is n long (where n is less than w), and you drop the needle many times and it crosses the edge of a slat with frequency f, then the value of pi_est = (2 * n) / (f * w). For example, if slats are w = 3 inches wide, a needle is n = 1 inch long, and you drop the needle 1,000 times, and it crossed an edge 210 times, then f = 210 / 1000 = 0.210 and pi_est = (2 * 1) / (0.21 * 3) = 3.1746.

Just for fun, I decided to code up a demo simulation. I saw many demos on the Internet but I didn’t want to be influenced by them, so I designed my simulation from scratch. In pseudo-code:

loop many times generate a random 1st point generate a random angle find 2nd point if line between points crosses edge num_hits = num_hits + 1 else num_misses = num_misses + 1 end-loop compute f compute pi_est

There were quite a few minor details. I set up a scenario with a slat width of 1.0 and a needle length of 0.5 and used 10,000 simulated drops. I didn’t use any fancy trigonometry or geometry (mostly because I was too lazy to look up the equations).

*I set up the simulation so that the first end point of a dropped needle had x-coordinate from 0 to 3, and therefore the second end point had x-coordinate from 0.5 to 3.5. A dropped needle could cross at x = 0, x = 1, x = 2, or x = 3.*

In one run of the demo, with 10,000 simulated drops, the needle hit an edge 3175 times so f = 0.3175 and the estimated value of pi was 3.1496. I kind of cheated by trying different values of the random number generator until I got a really nice estimate of pi.

*The Space Needle in Seattle (~600 ft, 1962) is a fantastic design and inspired many similar towers. Here are four. Skylon Tower (Niagara Falls, Canada, ~500 ft, 1965. Sky Tower (Auckland, ~750 ft, 1997). Stratosphere Hotel (Las Vegas, ~1100 ft, 1996). Macau Tower (Macau, ~1000 ft, 2001). I’ve been to all five of these cities but never had the desire to go to the top of the towers. For some reason, a view from a high location doesn’t interest me that much.*

# buffon.py # Buffon's Needle # replace "less-than" and "greater-than" with symbols import numpy as np np.random.seed(4) print("\nBegin Buffon's Needle problem simulation \n") width = 1.0 # floor slat width needle = 0.5 # needle length num_hits = 0 num_misses = 0 x_lo = 0.0; x_hi = 3.0 # 1st end point y_lo = 0.0; y_hi = 4.0 print("Starting simulation") for i in range(10000): x = (x_hi - x_lo) * np.random.random() + x_lo y = (y_hi - y_lo) * np.random.random() + y_lo angle = np.radians(360.0 * np.random.random()) # 0 to 2pi xx = x + needle * np.cos(angle) # 2nd end point yy = y + needle * np.sin(angle) if xx "less-than" x: (x, xx) = (xx, x) (y, yy) = (yy, y) # (x,y) now to left of (xx,yy) if (x "less-than" 0.0 and xx "greater-than" 0.0) \ or (x "less-than" 1.0 and xx "greater-than" 1.0) \ or (x "less-than" 2.0 and xx "greater-than" 2.0) \ or (x "less-than" 3.0 and xx "greater-than" 3.0): num_hits += 1 else: num_misses += 1 print("Simulation done \n") pr = (num_hits * 1.0) / (num_hits + num_misses) # frequency pi_est = (2.0 * needle) / (pr * width) print("Needle length: %0.1f " % needle) print("Slat width: %0.1f " % width) print("Number hits: " + str(num_hits)) print("Number misses: " + str(num_misses)) print("Probability of hitting crack: %0.4f" % pr) print("Estimate of pi: %0.4f" % pi_est) print("\nEnd simulation ")