Last active
March 30, 2016 00:33
-
-
Save CodeZombie/ef15d4d1b4ade2868e2b to your computer and use it in GitHub Desktop.
Pi Estimator using Montecarlo method in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
/ ######## | |
/ # ## # | |
/ # # # # | |
/ ## ## | |
/ # # | |
/ # # | |
/ ## ## | |
/ # # # # | |
/ # ## # | |
/ ######## | |
/ | |
/ This is an implementation of the Montecarlo method used to estimate Pi to 16 digits | |
/ It works by randomly choosing a point in a 1x1 square to 64bit floating point accuracy | |
/ This point is then checked to see if it is within a perfectly contained circle within this square using the formula: x^2 + y^2 < radius^2 | |
/ The number of points placed, and the number of points inside the circle are tracked | |
/ Pi is estimated by the following formua: (4 * <number of points in the circle>) / <number of points> | |
*/ | |
package main | |
import ( | |
"fmt" | |
"os" | |
"os/exec" | |
"math" | |
"math/rand" | |
"time" | |
) | |
func clearConsole() { //windows-only console-clear | |
cmd := exec.Command("cmd", "/c", "cls") | |
cmd.Stdout = os.Stdout | |
cmd.Run() | |
return | |
} | |
func printScreen(trials_ int, estPi_ float64, startTime_ time.Time) { | |
clearConsole() | |
elapsedTime := time.Since(startTime_) | |
fmt.Println("--------Montecarlo Pi Estimator--------") | |
fmt.Println("| Running... |") | |
fmt.Println("| |") | |
fmt.Printf( "| Trials: %-18d |\n", trials_) //pad and left-justify the number | |
fmt.Printf( "| Est of Pi: ~%-18g |\n", estPi_) | |
fmt.Println("| Actual Pi: 3.1415926535897932 |") | |
fmt.Printf( "| Run Time: %#18s |\n", fmt.Sprintf("%01d days %02d:%02d:%02d", uint32(elapsedTime.Hours())/24, | |
uint32(elapsedTime.Hours()) % 24, | |
uint32(elapsedTime.Minutes()) % 60, | |
uint32(elapsedTime.Seconds()) % 60)) | |
fmt.Println("---------------------------------------") | |
} | |
func main() { | |
totalCount, insideCount := 0, 0 | |
rand.Seed(time.Now().UTC().UnixNano()) //seed with a timestamp | |
startTime := time.Now() | |
printScreen(0, 0, startTime) | |
for true { | |
// checks to see if a randomly generated point is within a circle with a radius of 1 unit | |
// the formula for this is x^2 + y^2 < r^2, where x and y are random floats between 0 and 1, and r is 1 (1^2 == 1) | |
if math.Pow(rand.Float64(), 2) + math.Pow(rand.Float64(), 2) < 1 { | |
insideCount++ | |
} | |
totalCount++ | |
if totalCount % 10000000 == 0{ //only show output every ten million calculations. (becuase fmt.Print* is slow) | |
printScreen(totalCount, float64(4*insideCount)/float64(totalCount), startTime) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment