commit 314b8485bf5fd474f161cf3a034319547a190c22
parent 8c90478f7cbf04c3583a5dda6fc4020b069765a4
Author: Eamon Caddigan <eamon.caddigan@gmail.com>
Date: Mon, 9 Jan 2023 15:48:48 -0800
Solution to day 18, part 2.
Diffstat:
M | src/day_18.jl | | | 59 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
1 file changed, 54 insertions(+), 5 deletions(-)
diff --git a/src/day_18.jl b/src/day_18.jl
@@ -34,20 +34,29 @@ function parse_input(input::Vector{<:AbstractString})
Dict(Tuple(parse.(Int, split(x, ","))) => 6 for x in input)
end
-function neighbors(cube::Cube, cubes::Set{Cube})
+"""
+Return the six-connected neighborhood of the given cube.
+"""
+function neighbors(cube::Cube)
cubeneighbors = Set{Cube}()
for ax = 1:3, Δ = (-1, 1)
- cube₂ = Tuple(i==ax ? cube[i]+Δ : cube[i] for i in eachindex(cube))
- cube₂ ∈ cubes && push!(cubeneighbors, cube₂)
+ push!(cubeneighbors,
+ Tuple(i==ax ? cube[i]+Δ : cube[i] for i = eachindex(cube)))
end
cubeneighbors
end
+"""
+Loop through the cubes to find the droplet surface area.
+
+This updates the dictionary of (exposed) surface area values and also returns
+it (for convenience).
+"""
function updatecubes!(cubemap::Dict{Cube, Int})
cubes = Set(keys(cubemap))
while !isempty(cubes)
cube = pop!(cubes)
- for neighbor in neighbors(cube, cubes)
+ for neighbor in neighbors(cube) ∩ cubes
cubemap[cube] -= 1
cubemap[neighbor] -= 1
end
@@ -61,7 +70,47 @@ end
@assert part_1(example) == 64
@info part_1(input)
+"""
+Recursively calculate the surface area of the lava droplet.
+
+Pretty different than the part 1 approach--where we started in the droplet and
+worked outward, this starts in the steam and works toward the droplet. This
+function returns the surface area touched by the given cube and all heretofore
+unexplored cubes.
+"""
+function lavasurface!(steamarea::Dict{Cube, Int},
+ lavacubes::AbstractSet{Cube},
+ cube::Cube,
+ xrange::Tuple{Int, Int} = extrema(x -> x[1], lavacubes),
+ yrange::Tuple{Int, Int} = extrema(x -> x[2], lavacubes),
+ zrange::Tuple{Int, Int} = extrema(x -> x[3], lavacubes))
+ @assert cube ∉ lavacubes
+ @assert cube ∉ keys(steamarea)
+ steamarea[cube] = 0
+ for neighbor = neighbors(cube)
+ if neighbor ∈ lavacubes
+ steamarea[cube] += 1
+ elseif neighbor ∉ keys(steamarea) &&
+ xrange[1]-1 <= neighbor[1] <= xrange[2]+1 &&
+ yrange[1]-1 <= neighbor[2] <= yrange[2]+1 &&
+ zrange[1]-1 <= neighbor[3] <= zrange[2]+1
+ steamarea[cube] += lavasurface!(steamarea, lavacubes, neighbor,
+ xrange, yrange, zrange)
+ end
+ end
+ steamarea[cube]
+end
+
function part_2(input)
- nothing
+ steamarea = Dict{Cube, Int}()
+ lavacubes = keys(parse_input(input))
+
+ xrange = extrema(x -> x[1], lavacubes)
+ yrange = extrema(x -> x[2], lavacubes)
+ zrange = extrema(x -> x[3], lavacubes)
+
+ lavasurface!(steamarea, lavacubes, (xrange[1]-1, yrange[1]-1, zrange[1]-1),
+ xrange, yrange, zrange)
end
+@assert part_2(example) == 58
@info part_2(input)