Skip to content

Instantly share code, notes, and snippets.

@128keaton
Last active April 26, 2017 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 128keaton/bd617e76cf6ba7801ab0e8682db48ceb to your computer and use it in GitHub Desktop.
Save 128keaton/bd617e76cf6ba7801ab0e8682db48ceb to your computer and use it in GitHub Desktop.
Calculating Pi with a Dartboard
import UIKit
import PlaygroundSupport
import SpriteKit
/*: pidarts.playground
# Calculating Pi with a Dart Board
____________
## a.k.a. "Monte Carlo algorithm"
To calculate pi for a circle inside of a square, we throw darts at the square and tally up the ones in the circle and tally up the ones outside of the circle separately.
____________
## Building the dartboard:
*/
var minCoord: CGFloat = -1
var maxCoord: CGFloat = 1
var radius = (maxCoord - minCoord) + minCoord
var circleArea: CGFloat = 2 * CGFloat((pow(minCoord, 2) + pow(maxCoord, 2)))
/*:
Above, we set the max and min coordinates to be `1` and `-1` respectively, making our radius `2`, and our square area `4`
____________
## Gathering and counting the darts:
*/
var dartsInCircle: CGFloat = 0
var dartsThrown: CGFloat = 1000
/*:
Above, we bought a thousand darts (`1000`) and, right now, we have no darts in the circle, because we haven't
thrown them.
____________
## Lets Throw:
*/
UIGraphicsBeginImageContextWithOptions(CGSize(width: (radius * 2) * 100, height: (radius * 2) * 100), false, 0)
let board = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: (radius * 2) * 100 , height: (radius * 2) * 100))
UIColor.green.setStroke()
board.stroke()
board.lineWidth = 2.0
for dart in 1...Int(dartsThrown) {
let dartX = CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(maxCoord - minCoord) + min(maxCoord, minCoord)
let dartY = CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(maxCoord - minCoord) + min(maxCoord, minCoord)
let p = UIBezierPath(ovalIn: CGRect(x: dartX * ((radius * 2) * 100), y: dartY * ((radius * 2) * 100), width: 10, height: 10))
UIColor.red.setFill()
p.fill()
if pow(dartX, 2) + pow(dartY, 2) < radius {
dartsInCircle += 1
}
}
/*:
____________
## Final Count and Estimation:
Phew! My arm is tired! So we threw all the darts and counted the final figures.
*/
"Darts thrown: \(dartsThrown)"
"Darts inside the circle: \(dartsInCircle)"
/*:
And finally we can estimate for pi:.
*/
"Pi estimate: \(CGFloat(circleArea * dartsInCircle / dartsThrown))"
let im = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: (radius * 2) * 100, height: (radius * 2) * 100))
containerView.addSubview(UIImageView(image: im))
PlaygroundPage.current.liveView = containerView
include Math
# Define the coordinates and variables
minCoord = -1.0
maxCoord = 1.0
radius = maxCoord
circleArea = 4
inCircleCount = 0
# Get the first variable passed
dartsThrownCount = 10
dartsThrownCount = ARGV[0].to_f if ARGV[0]
# Loop through all the numbers
(0..dartsThrownCount).each do |_count|
# Calculate the random coordinate
dartX = rand(minCoord..maxCoord)
dartY = rand(minCoord..maxCoord)
# Checks to see if the dart is in the circle
if dartX**2 + dartY**2 < radius
# Adds another dart to the circle count
inCircleCount += 1
end
end
puts "Darts inside the circle #{inCircleCount}"
puts "Darts thrown: #{dartsThrownCount}"
puts "Pi estimate: #{circleArea * (inCircleCount / dartsThrownCount)}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment