96 lines
2.5 KiB
Swift
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)
|
|
}
|
|
}
|