Skip to content

Instantly share code, notes, and snippets.

@johnhaney
Last active March 14, 2026 16:27
Show Gist options
  • Select an option

  • Save johnhaney/a8ff84417d53847b9b2f284175b9e2ec to your computer and use it in GitHub Desktop.

Select an option

Save johnhaney/a8ff84417d53847b9b2f284175b9e2ec to your computer and use it in GitHub Desktop.
Calculate PI
//
// ContentView.swift
// CalculatePi
//
// Created by John Haney on 3/14/24.
//
import SwiftUI
import Combine
struct ContentView: View {
@State var sticks: [(CGPoint, CGPoint)] = []
@State var timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
var sticksCrossing: Int {
sticks.filter({
let bottom: CGFloat = 40.0 * ceil($0.0.y / 40.0)
let top: CGFloat = $0.1.y
return bottom < top
}).count
}
var estimation: CGFloat {
let crossing = sticksCrossing
guard crossing > 0 else { return 0 }
return 2 * CGFloat(sticks.count) / CGFloat(crossing)
}
var body: some View {
VStack {
Text("Sticks: \(sticks.count)")
Text("Sticks Crossing: \(sticksCrossing)")
Text("Pi: \(estimation)")
Canvas { context, size in
do {
var path = Path()
path.addRects([
CGRect(x: 0, y: 0, width: size.width, height: size.height*0.1),
CGRect(x: 0, y: size.height*0.2, width: size.width, height: size.height*0.1),
CGRect(x: 0, y: size.height*0.4, width: size.width, height: size.height*0.1),
CGRect(x: 0, y: size.height*0.6, width: size.width, height: size.height*0.1),
CGRect(x: 0, y: size.height*0.8, width: size.width, height: size.height*0.1),
])
context.fill(path, with: .color(.gray))
}
var path = Path()
for (point, point2) in sticks {
path.move(to: point)
path.addLine(to: point2)
}
context.stroke(path, with: .color(.orange))
}
.frame(width: 300, height: 400)
Button("Drop") {
dropStick()
}
}
.monospacedDigit()
.onReceive(timer, perform: { _ in
dropStick()
})
}
func dropStick() {
let x = CGFloat.random(in: 40...260)
let y = CGFloat.random(in: 40...360)
let angle = Angle(degrees: .random(in: 0...360))
let x2 = x + 40 * cos(angle.radians)
let y2 = y + 40 * sin(angle.radians)
let points = [
CGPoint(x: x, y: y),
CGPoint(x: x2, y: y2)
].sorted(by: { $0.y < $1.y })
sticks.append((points[0], points[1]))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment