Day 22 part 2
This commit is contained in:
parent
1923e8ec0b
commit
6427bb0aac
1 changed files with 67 additions and 31 deletions
98
day22.swift
98
day22.swift
|
@ -3,44 +3,57 @@ import Foundation
|
||||||
@main
|
@main
|
||||||
struct Day22: Puzzle {
|
struct Day22: Puzzle {
|
||||||
func run() {
|
func run() {
|
||||||
var cube: [Point: Bool] = [:]
|
|
||||||
let activeRange = -50...50
|
|
||||||
|
|
||||||
let scanner = Scanner(string: input)
|
let scanner = Scanner(string: input)
|
||||||
|
var cubes: [Cube] = []
|
||||||
|
|
||||||
while !scanner.isAtEnd {
|
while !scanner.isAtEnd {
|
||||||
let (command, xrange, yrange, zrange) = scanner.line()
|
cubes.append(scanner.cube())
|
||||||
if let xrange = xrange.intersection(with: activeRange) {
|
|
||||||
for x in xrange.clamped(to: activeRange) {
|
|
||||||
if let yrange = yrange.intersection(with: activeRange) {
|
|
||||||
for y in yrange.clamped(to: activeRange) {
|
|
||||||
if let zrange = zrange.intersection(with: activeRange) {
|
|
||||||
for z in zrange.clamped(to: activeRange) {
|
|
||||||
cube[Point(x: x, y: y, z: z)] = command
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xStepsSet: Set<Int> = []
|
||||||
|
var yStepsSet: Set<Int> = []
|
||||||
|
var zStepsSet: Set<Int> = []
|
||||||
|
|
||||||
var sum = 0
|
for cube in cubes {
|
||||||
for x in activeRange {
|
xStepsSet.insert(cube.start.x)
|
||||||
for y in activeRange {
|
xStepsSet.insert(cube.end.x + 1)
|
||||||
for z in activeRange {
|
yStepsSet.insert(cube.start.y)
|
||||||
sum += cube[Point(x: x, y: y, z: z), default: false] ? 1 : 0
|
yStepsSet.insert(cube.end.y + 1)
|
||||||
|
zStepsSet.insert(cube.start.z)
|
||||||
|
zStepsSet.insert(cube.end.z + 1)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
print("Part 1:", sum)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ClosedRange {
|
var xSteps = xStepsSet.sorted()
|
||||||
func intersection(with other: Self) -> Self? {
|
var ySteps = yStepsSet.sorted()
|
||||||
guard upperBound >= other.lowerBound && lowerBound <= other.upperBound else { return nil }
|
var zSteps = zStepsSet.sorted()
|
||||||
return clamped(to: other)
|
|
||||||
|
let firstX = xSteps.removeFirst()
|
||||||
|
let firstY = ySteps.removeFirst()
|
||||||
|
let firstZ = zSteps.removeFirst()
|
||||||
|
|
||||||
|
var part2 = 0
|
||||||
|
|
||||||
|
var x0 = firstX
|
||||||
|
for x in xSteps {
|
||||||
|
let possibleX = cubes.filter { $0.xRange.overlaps(x0..<x) }
|
||||||
|
var y0 = firstY
|
||||||
|
for y in ySteps {
|
||||||
|
let possibleY = possibleX.filter { $0.yRange.overlaps(y0..<y) }
|
||||||
|
var z0 = firstZ
|
||||||
|
for z in zSteps {
|
||||||
|
let state = possibleY.lazy.reversed().first { $0.zRange.overlaps(z0..<z) }?.state ?? false
|
||||||
|
|
||||||
|
if state {
|
||||||
|
part2 += (x - x0) * (y - y0) * (z - z0)
|
||||||
|
}
|
||||||
|
z0 = z
|
||||||
|
}
|
||||||
|
y0 = y
|
||||||
|
}
|
||||||
|
x0 = x
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Part 2:", part2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +63,20 @@ struct Point: Hashable {
|
||||||
var z: Int
|
var z: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Cube {
|
||||||
|
var start: Point
|
||||||
|
var end: Point
|
||||||
|
var state: Bool
|
||||||
|
|
||||||
|
var xRange: ClosedRange<Int> { start.x...end.x }
|
||||||
|
var yRange: ClosedRange<Int> { start.y...end.y }
|
||||||
|
var zRange: ClosedRange<Int> { start.z...end.z }
|
||||||
|
|
||||||
|
func contains(_ point: Point) -> Bool {
|
||||||
|
xRange.contains(point.x) && yRange.contains(point.y) && zRange.contains(point.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Scanner {
|
extension Scanner {
|
||||||
func onOff() -> Bool {
|
func onOff() -> Bool {
|
||||||
if scanString("on") != nil {
|
if scanString("on") != nil {
|
||||||
|
@ -84,6 +111,15 @@ extension Scanner {
|
||||||
let zRange = range()
|
let zRange = range()
|
||||||
return (command, xRange, yRange, zRange)
|
return (command, xRange, yRange, zRange)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cube() -> Cube {
|
||||||
|
let (state, xrange, yrange, zrange) = line()
|
||||||
|
return Cube(
|
||||||
|
start: Point(x: xrange.lowerBound, y: yrange.lowerBound, z: zrange.lowerBound),
|
||||||
|
end: Point(x: xrange.upperBound, y: yrange.upperBound, z: zrange.upperBound),
|
||||||
|
state: state
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = """
|
let input = """
|
||||||
|
|
Loading…
Add table
Reference in a new issue