π-time!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import System.Random   -- or import Random, 
                       -- depending on your version of the 
                       -- standard Haskell libraries                      

{--

Now for something completely different ...

π-time!

So, one way to compute the EXACT value of π is ... well, NOT to.

BUT there are good enough close-approximations, some going on for even 
zillions of digits.

'zillions' is a number: it means: 'zillions.'

The usual approximation given in schools and such is 22 / 7, but that's just
an atrocity to the name of π! And we will not stand for it!

So, to compute π.

It's simple, really. We know that the area of a circle is πr² so we just pick
some 'reasonable' r, 'draw' that circle on a 'piece of paper,' tack that 
paper on the wall and start throwing darts at it. The imprint of the dart is
an area, see? So, we sum up all those areas that fall within the circle
(discarding all the misses and scold ourselves to try harder next time!), and
we have an approximation of π!

Simple.

The more darts thrown, and the smaller the dart-leave, with respect to the 
size of the circle, the closer the approximation to π.

For example, if we have a circle of radius 1 square ... whatever: feet?
decimeters? Do people seriously measure dart-boards in decimeters? Seriously?

... and people say, 'Ooh! Metrics! So the superior!' But when I want a pint
of beer, I want a pint of beer, not a ha'-liter, or whatever! But I digress
(and in a very George Orwellian-1984escque-way, too, at that).

At any rate, so we have the dart board of radius 1, and we have a dart that
leaves an imprint of one square ... okay, seriously? decimeters? Then we know
exactly one dart will hit and be completely within the mark, and exactly all
other non-overlapping throws will miss the target.

From that example we have computed π.

π == 1 in that case.

So, to keep things entirely in the integral domain (halves? quarters? We no
need no steekin' quarters ... unless they are leg-quarters. Yum!)

(For you vegans out there or those who abstain from meat, I'm talking about
ZUCCHINI leg-quarters, okay?)

(Digression again, in case you didn't notice. Back on topic.)

So, to keep things entirely in the integral domain, we keep our dart-leave
the same (one square ... whatever, millimeter, okay? you happy?) and we increase
the size of our radius, using the same unit of measure, so now the radius is
100 milimeters. We throw LOTS of darts at our cartesian grid, oops, sorry! I
meant to say 'dart board,' and exclude all misses and we have a new
approximation of π.

So:

 --}

type Radius = Integer
type Π = Integer

π' :: Radius -> Integer -> IO Π -- see UPDATE below
             -- IO to seed the randomness from the 'RealWorld.'
π' r numberOfDartsToThrow = undefined

-- what (scaled) values of π do you come up with?

{--

Hint: there is a 'trick' that this old fox did not make explicit, so I
will do that now: the dart board is inside the circle? No, it contains
the circle, right? That's my hint. Go to town.

 --}

-- UPDATE! ------------------------------------------------------------

{--

Okay, so the dart thingie was a 'great idea' in theory, but in practice,
that is, in implementation, ... not so great.

What we really want is ALL the points within the circle, so this gets rid
of the whole dart-throwing paradigm ... just iterate over every point in
the grid, inclusive and exclusive and sum the inclusive points. DONE!

So, with that:

 --}

π :: Radius -> Π
π r = undefined