aoc2021/Sources/17/17.swift
2021-12-17 07:02:13 +01:00

96 lines
2.5 KiB
Swift

//
// File.swift
//
//
// Created by Max Nuding on 17.12.21.
//
import Foundation
import Runner
import Collections
struct Point:Hashable {
var x: Int
var 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 {
point.y < botRight.y || point.x > botRight.x
}
}
struct Probe {
var position = Point(x: 0, y: 0)
var velocity: Point
mutating func move() {
position.x += velocity.x
position.y += velocity.y
if velocity.x < 0 {
velocity.x += 1
} else if velocity.x > 0 {
velocity.x -= 1
}
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 = [Point]()
found.reserveCapacity(3000)
for x in 0...500 {
for y in -500...500 {
let velocity = Point(x: x, y: y)
var probe = Probe(velocity: velocity)
var maxYCurrent = Int.min
repeat {
probe.move()
if probe.position.y > maxYCurrent {
maxYCurrent = probe.position.y
}
if area.contains(point: probe.position) {
if maxYCurrent > maxY {
maxY = maxYCurrent
}
found.append(velocity)
break
}
} while !area.overshot(point: probe.position)
}
}
print(maxY)
print(Set(found).count)
}
}