-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.swift
59 lines (50 loc) · 2.22 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
import Foundation
func main() throws {
let input: [String] = try readInput(fromTestFile: false)
let cubes: Set<[Int]> = Set(input.map({ $0.components(separatedBy: ",").map({ Int($0)! }) }))
/**
For part one, loop through all cubes and get their adjacent cubes.
If an adjacent cube is not a lava cube, then add it to the dict with a value of one.
If it already exists in the dict, add one to it
The dict represents the number of solid neighbours that an air block has
After building the dict, add up all of the value to get the number of lava cube sides that touch air
*/
var numberOfCubeNeighboursPerAir: [[Int]: Int] = [:]
for cube in cubes {
let adjacents = getAdjacents(cube)
for a in adjacents.filter({ !cubes.contains($0) }) {
numberOfCubeNeighboursPerAir[a] = (numberOfCubeNeighboursPerAir[a] ?? 0) + 1
}
}
print(numberOfCubeNeighboursPerAir.values.reduce(0, +))
/**
For part two, use DFS to get a set of cubes that are visitable. A cube is visitable if there is a path to it that is not blocked by a lava block.
Next, tot up the values from part one where the air block is in the visitable set.
*/
let maxDimension = cubes.flatMap({ $0 }).max()! + 2
let minDimension = cubes.flatMap({ $0 }).min()! - 2
var queue = [[0, 0, 0]]
var visited: Set<[Int]> = []
while !queue.isEmpty {
let current = queue.popLast()!
visited.insert(current)
for adjacent in getAdjacents(current) {
if visited.contains(adjacent) { continue }
if cubes.contains(adjacent) { continue }
if adjacent.min()! < minDimension || adjacent.max()! > maxDimension { continue }
queue.append(adjacent)
}
}
print(numberOfCubeNeighboursPerAir.filter({ visited.contains($0.key) }).values.reduce(0, +))
}
private func getAdjacents(_ cube: [Int]) -> [[Int]] {
[
[0 + cube[0], 0 + cube[1], 1 + cube[2]],
[0 + cube[0], 0 + cube[1], -1 + cube[2]],
[0 + cube[0], 1 + cube[1], 0 + cube[2]],
[0 + cube[0], -1 + cube[1], 0 + cube[2]],
[1 + cube[0], 0 + cube[1], 0 + cube[2]],
[-1 + cube[0], 0 + cube[1], 0 + cube[2]]
]
}
Timer.time(main)