Programming Praxis – Buffon’s Needle

In today’s Programming Praxis exercise, our goal is to approximate pi by using Georges-Louis Leclerc’s method of dropping needles on a board. Let’s get started, shall we?

import Control.Applicative
import System.Random

We’re going to be needing two sets of random numbers; one for the position and one for the angle of the needles. In order to save some code and to stop Haskell complaining about ambiguous types we make a function to generate an infinite amount of numbers in the [0,1) range.

rnds :: IO [Double]
rnds = fmap randoms newStdGen

We approximate pi by dividing the total amount of needles dropped by the number of needles that hit a line.

buffon :: Int -> IO Double
buffon n = (fromIntegral n /) . sum . take n <$>
    (zipWith (\y t -> if y < sin (t*pi/2) / 2 then 1 else 0) <$> rnds <*> rnds)

Running the simulation reveals that this isn’t a very practical way of approximating pi: after one million needles it generally only has two correct digits.

main :: IO ()
main = print =<< buffon 1000000

Tags: , , , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: