@main struct Day17: Puzzle { func run() { var maxHeight: Int = 0 var count = 0 for speedX in 1..<300 { for speedY in -600..<300 { if case .hit(let height) = run(vx: speedX, vy: speedY) { maxHeight = max(height, maxHeight) count += 1 } } } print("Part 1:", maxHeight) print("Part 2:", count) } enum Result { case tooFar case tooShort case hit(height: Int) } struct Vector: Hashable { var x: Int var y: Int } func run(vx: Int, vy: Int) -> Result { var state = State(vx: vx, vy: vy) while state.x <= xMax && state.y >= yMin { state.step() if xMin...xMax ~= state.x && yMin...yMax ~= state.y { return .hit(height: state.maxHeight) } } if state.x > xMax { return .tooFar } return .tooShort } struct State { var vx: Int var vy: Int var x: Int = 0 var y: Int = 0 var maxHeight = 0 mutating func step() { if y > maxHeight { maxHeight = y } x += vx y += vy vx -= vx.signum() vy -= 1 } } // target area: x=138..184, y=-125..-71 let xMin = 138 let xMax = 184 let yMin = -125 let yMax = -71 }