-
Notifications
You must be signed in to change notification settings - Fork 0
/
Solution_2018_12.swift
77 lines (63 loc) · 2.3 KB
/
Solution_2018_12.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
import Foundation
private enum State: String {
case dead = "."
case alive = "#"
}
struct Solution_2018_12: Solution {
var input: Input
func run() throws {
let input = try self.input.get()
.components(separatedBy: .newlines)
let initialState = input[0][input[0].firstIndex(where: { $0 == "." || $0 == "#" })!...]
.map({ State(rawValue: String($0))! })
let length = initialState.count
let rules = input[2...]
.reduce(into:[[State]:State]()) { acc, str in
let pattern = str[...str.index(str.startIndex, offsetBy: 4)]
.map({ State(rawValue: String($0))! })
let result = State(rawValue: String(str.last!))!
acc[pattern] = result
}
var state = [State](repeating:.dead, count:length * 4)
for i in 0..<length {
state[i + length] = initialState[i]
}
func tick(_ state: [State]) -> [State] {
var newState = [State](repeating:.dead, count:state.count)
for i in state.indices {
guard i >= 2, i < state.count - 2 else { continue }
newState[i] = rules[Array(state[(i-2)...(i+2)])]!
}
return newState
}
for _ in 0..<20 {
state = tick(state)
}
func calc(_ state: [State]) -> Int {
return state.enumerated().reduce(0) { acc, x in
if x.element == .dead {
return acc
}
return acc + (x.offset - length)
}
}
let part1 = calc(state)
print(part1)
// if we continue `tick()`ing, we'll get to the point when all the flowers
// are travelling to the right one pot a tick in a stable formation
// debug printing showed that 200 iterations is enough
let iterations = 200
for _ in 20..<(iterations - 1) {
state = tick(state)
}
let value1 = calc(state)
state = tick(state)
let value2 = calc(state)
let diff = value2 - value1
let part2 = (50_000_000_000 - iterations) * diff + value2
print(part2)
// ------- Test -------
assert(part1 == 2049, "WA")
assert(part2 == 2300000000006, "WA")
}
}