aoc2021/Sources/17/17.swift

96 lines
2.5 KiB
Swift
Raw Normal View History

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