-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.swift
executable file
·82 lines (66 loc) · 2.16 KB
/
main.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
import Foundation
func main() throws {
let isTestMode = CommandLine.arguments.contains("test")
let input: [String] = try readInput(fromTestFile: isTestMode)
var game = Game(input)
for _ in 0..<100 { game.tick() }
print("Part 1:", game.flashesPerformed)
game = Game(input)
var counter = 0
while !game.allPositionFlashedOnPreviousTick {
game.tick()
counter += 1
}
print("Part 2:", counter)
}
class Game {
private var board: [[Int]]
private var prevFlashed: Set<Coordinate> = []
var flashesPerformed = 0
var allPositionFlashedOnPreviousTick: Bool {
prevFlashed.count == (board.count * board[0].count)
}
init(_ startingBoard: [String]) {
board = startingBoard.map({ [Character]($0).map({ Int($0)! }) })
}
func tick() {
// Increase each by one
for y in 0..<board.count {
for x in 0..<board[y].count {
board[y][x] += 1
}
}
// Perform the flashing
var flashedCoords = Set<Coordinate>()
var flashableCoords = getFlashableCoords(flashed: flashedCoords)
while !flashableCoords.isEmpty {
for f in flashableCoords {
flashedCoords.insert(f)
flashesPerformed += 1
let adjacents = f.getAdjacents(in: board)
for a in adjacents {
board[a.y][a.x] += 1
}
}
flashableCoords = getFlashableCoords(flashed: flashedCoords)
}
// If coords have flashed, set them back to 0
for f in flashedCoords {
board[f.y][f.x] = 0
}
prevFlashed = flashedCoords
}
private func getFlashableCoords(flashed: Set<Coordinate>) -> Set<Coordinate> {
var flashableCoords: Set<Coordinate> = []
for y in 0..<board.count {
for x in 0..<board[y].count {
let coordinate = Coordinate(x, y)
if board[y][x] > 9 && !flashed.contains(coordinate) {
flashableCoords.insert(coordinate)
}
}
}
return flashableCoords
}
}
Timer.time(main)