-
Notifications
You must be signed in to change notification settings - Fork 0
/
Solution_2018_10.swift
98 lines (80 loc) · 2.83 KB
/
Solution_2018_10.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import Foundation
private struct Point {
var position: (x: Int, y: Int)
let velocity: (x: Int, y: Int)
func tick() -> Point {
return Point(
position: (
x: position.x + velocity.x,
y: position.y + velocity.y
),
velocity: velocity
)
}
}
extension Point {
init(_ description: String) {
let pattern = "position=<\\s*(?<pX>-?\\d+),\\s*(?<pY>-?\\d+)>\\s*velocity=<\\s*(?<vX>-?\\d+),\\s*(?<vY>-?\\d+)>"
let regex = try! NSRegularExpression(pattern: pattern)
let captureGroupToInt = regex.captureGroupToInt(in: description)
guard let pX = captureGroupToInt("pX") else {
fatalError("Wrong input format")
}
guard let pY = captureGroupToInt("pY") else {
fatalError("Wrong input format")
}
guard let vX = captureGroupToInt("vX") else {
fatalError("Wrong input format")
}
guard let vY = captureGroupToInt("vY") else {
fatalError("Wrong input format")
}
self.init(position: (x: pX, y: pY), velocity: (x: vX, y: vY))
}
}
struct Solution_2018_10: Solution {
var input: Input
func run() throws {
var input = try self.input.get()
.components(separatedBy: .newlines)
.map({ Point($0) })
func minmax(_ xs: [Point], _ transform: (Point) -> Int) -> (Int, Int) {
return xs.map(transform).reduce((Int.max,Int.min), {
(min($0.0, $1), max($0.1, $1))
})
}
func minmaxX(_ xs: [Point]) -> (Int, Int) {
return minmax(xs, { $0.position.x })
}
func minmaxY(_ xs: [Point]) -> (Int, Int) {
return minmax(xs, { $0.position.y })
}
var (minY, maxY) = minmaxY(input)
var iterations = 0
// kinda cheating, I debug printed it until getting an answer
// so I know the point that we need to simulate to
while maxY - minY != 9 {
input = input.map({ $0.tick() })
(minY, maxY) = minmaxY(input)
iterations += 1
}
func printGrid(_ xs: [Point]) {
let (minX, maxX) = minmaxX(xs)
let (minY, maxY) = minmaxY(xs)
var grid = [[String]](repeating: [String](repeating: ".", count: maxX-minX+1), count: maxY-minY+1)
input.forEach({
grid[$0.position.y-minY][$0.position.x-minX] = "#"
})
grid.forEach({
print($0.joined(separator:""))
})
}
// ...aaaaand I was also too lazy to come up with the way to parse letters :(
printGrid(input)
let part2 = iterations
print(part2)
// ------- Test -------
//assert(part1 == "PPNJEENH", "WA")
assert(part2 == 10375, "WA")
}
}