Jump to content

Calculating pi with hot dogs


Freak
 Share

Recommended Posts

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:

BGtqHTf.jpg

 

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:

0UE3bR4.png

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);

 

  • I Like This! 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...