// // File.swift // // // Created by Max Nuding on 17.12.21. // import Foundation import Runner import Collections struct Point:Hashable { let x: Int let y: Int } struct Area { let topLeft: Point let botRight: Point init(x: String, y: String) { let xVals = x[x.index(x.startIndex, offsetBy: 2)...].components(separatedBy: "..").map { Int($0)! } let yVals = y[y.index(y.startIndex, offsetBy: 2)...].components(separatedBy: "..").map { Int($0)! } topLeft = Point(x: xVals.first!, y: yVals.last!) botRight = Point(x: xVals.last!, y: yVals.first!) } func contains(point: Point) -> Bool { point.x >= topLeft.x && point.x <= botRight.x && point.y <= topLeft.y && point.y >= botRight.y } func overshot(point: Point) -> Bool { overshotX(point: point) || overshotY(point: point) } func overshotX(point: Point) -> Bool { point.x > botRight.x } func overshotY(point: Point) -> Bool { point.y < botRight.y } } struct Probe { var position: Point var velocity: Point mutating func move() { position = Point(x: position.x + velocity.x, y: position.y + velocity.y) var dX: Int switch velocity.x { case _ where velocity.x < 0: dX = 1 case 0: dX = 0 case _ where velocity.x > 0: dX = -1 default: fatalError() } velocity = Point(x: velocity.x + dX, y: velocity.y - 1) } } class Day17: Runnable { let inputPath: String required init(inputPath: String) { self.inputPath = inputPath } public func run() { let input = try! String(contentsOfFile: inputPath) let parts = input .trimmingCharacters(in: .newlines) .components(separatedBy: ": ") .last! .components(separatedBy: ", ") let area = Area(x: parts.first!, y: parts.last!) var maxY = Int.min var found = Set() for x in -500...500 { for y in -500...500 { let velocity = Point(x: x, y: y) var probe = Probe(position: Point(x: 0, y: 0), velocity: velocity) var maxYCurrent = Int.min while !area.contains(point: probe.position) && !area.overshot(point: probe.position) { probe.move() if probe.position.y > maxYCurrent { maxYCurrent = probe.position.y } } if area.contains(point: probe.position) { if maxYCurrent > maxY { maxY = maxYCurrent } found.insert(velocity) } } } print(maxY) print(found.count) } }