AoC/day17/main.swift
2020-12-17 07:40:19 +01:00

100 lines
2.5 KiB
Swift

import Foundation
let input = loadData(day: 17).lines()
struct Coordinate: Hashable {
var x, y, z, w: Int
}
struct Cube {
var cube: [Coordinate: Bool] = [:]
var minX = 0
var maxX = 0
var minY = 0
var maxY = 0
var minZ = 0
var maxZ = 0
var minW = 0
var maxW = 0
func neighbors(_ c: Coordinate) -> Int {
var count = 0
for xOffset in -1...1 {
for yOffset in -1...1 {
for zOffset in -1...1 {
for wOffset in -1 ... 1 {
guard !(xOffset == 0 && yOffset == 0 && zOffset == 0 && wOffset == 0) else { continue }
let current = Coordinate(x: c.x + xOffset, y: c.y + yOffset, z: c.z + zOffset, w: c.w + wOffset)
if let value = cube[current], value {
count += 1
}
}
}
}
}
return count
}
subscript(_ x: Int, _ y : Int, _ z : Int, _ w : Int ) -> Bool {
get {
cube[Coordinate(x: x, y: y, z: z, w: w)] ?? false
}
set {
cube[Coordinate(x: x, y: y, z: z, w: w)] = newValue
if newValue {
minX = min(x, minX)
minY = min(y, minY)
minZ = min(z, minZ)
maxX = max(x, maxX)
maxY = max(y, maxY)
maxZ = max(z, maxZ)
minW = min(w, minW)
maxW = max(w, maxW)
}
}
}
}
var cube = Cube()
func cycle() -> Cube {
var result = cube
for x in cube.minX - 1 ... cube.maxX + 1 {
for y in cube.minY - 1 ... cube.maxY + 1 {
for z in cube.minZ - 1 ... cube.maxZ + 1 {
for w in cube.minW - 1 ... cube.maxW + 1 {
let n = cube.neighbors(Coordinate(x: x, y: y, z: z, w: w))
if cube[x, y, z, w] {
if n < 2 || n > 3 {
result[x, y, z, w] = false
}
} else {
if n == 3 {
result[x, y, z, w] = true
}
}
}
}
}
}
return result
}
for (y, line) in input.enumerated() {
for (x, char) in line.enumerated() {
cube[x, y, 0, 0] = char == "#"
}
}
for _ in 0..<6 {
cube = cycle()
}
print(cube.cube.values.reduce(0, { $0 + ($1 ? 1 : 0) }))