This is a program that I wrote a few years ago in order to test a theory that I read online. I read on some website that you could calculate the value of pi by throwing hot dogs on the floor which absolutely blew me away. I couldn't believe it, so I decided to test it. I wrote a program to simulate throwing 1 billion hot dogs on the floor and by golly let me tell you, they're right. Here's how:
(Technically this works with any stick-like object.)
Let x be the length of our object (hot dog in our case). You must then draw lines on the floor perpendicular to the direction you're facing which are all x length apart. This elegantly drawn image demonstrates what I mean flawlessly:
The number of hot dogs which landed on a line divided by the total number of hot dogs thrown is an approximation for pi.
Like I said, I simply refused to believe that something so simple could be possible so I wrote a program to simulate the process:
#!/usr/bin/perl -w
use strict;
my($dist, $lower, $upper, $lenComponent, $approx);
my $len = 6;
my $throws = 1000000; #CHANGE TO WHAT YOU WANT
my $intersects = 0;
for(1..$throws){
$dist = rand(180); #arbitrary maximum throwing distance
$lenComponent = sin(rand(6.28318530718))*$len; #trig with up to 2pi radians rotation
$lower = $dist - ($lenComponent/2);
$upper = $lower + $lenComponent;
for(my $line = 0; $line<=($dist+$len); $line+=$len){
if($line>=$lower and $line<=$upper){
++$intersects;
last;
}
}
}
$approx = (1/$intersects)*$throws;
print "Pi is approximately: $approx";
And I ran the program overnight with 1 BILLION hot dogs, which yielded this result:
3.14154932843791
VS
3.14159265358979
Error:
0.00004332515
Wowza!
I also wrote a second version of the program which uses multi-threading to throw the hot dogs faster. It was actually a neat exercise because I wrote it such that all of the threads can edit the same variable which counts the total number of intersections. Code:
#!usr/bin/perl -w
use strict;
use threads;
use threads::shared;
my $intersects :shared = 0;
my $throws = 10000000;
my @threads = ();
sub hotdog{
my($dist, $lenComponent, $lower, $upper);
my $len = 1;
for(1..$throws){
$dist = rand(5); #arbitrary maximum throwing distance
$lenComponent = sin(rand(6.28318530718))*$len; #trig with up to 2pi radians rotation
$lower = $dist - ($lenComponent/2);
$upper = $dist + ($lenComponent/2);
for(my $line = 0; $line<=($dist+$len); $line+=$len){
if($line>=$lower and $line<=$upper){
lock($intersects);
++$intersects;
last;
}
}
}
}
for(1..10){
push (@threads, threads->create(\&hotdog));
}
$_->join foreach @threads;
print "Pi is approximately: ".(($throws*scalar(@threads))/$intersects);