My (attempted) solutions to the 2022 Advent of Code
Log | Files | Refs | README

```commit 68a681fe37b7d4d877442c0140b8c9767656ff71
parent 74fb77374becc1820d19220bf8d28378e8bff3ef
Date:   Wed, 14 Dec 2022 10:38:01 -0800

Solution to day 14, part 2.

I was so emotionally prepared for my implementation to completely fall
apart for part 2, but it turns out that I only needed to make some minor
changes, lol. I will confess to you, stranger who actually reads these
commit messages, that I had a couple infinite loop bugs to track down
before this actually worked. But it was overall straightforward and
satisfying.

Diffstat:
Msrc/day_14.jl | 22+++++++++++++---------
```
```1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/day_14.jl b/src/day_14.jl
@@ -13,9 +13,11 @@ module Maps
struct MapState
filled_blocks::Set{Tuple{Int,Int}}
lowest_row::Int
+       has_floor::Bool
end

-    function MapState(input::Vector{<:AbstractString})
+    function MapState(input::Vector{<:AbstractString},
filled_blocks = Set{Tuple{Int,Int}}()
lowest_row = -Inf
for path = input
@@ -31,7 +33,7 @@ module Maps
end
end
end
-        MapState(filled_blocks, lowest_row)
end

# I'm going to try to keep these function signatures implementation-neutral
@@ -42,14 +44,15 @@ module Maps
Return true IFF sand at the given coordinate is destined to fall forever.
"""
function isfallingforever(mapstate::MapState, coord::Tuple{Int,Int})
-        coord[2] > mapstate.lowest_row
+        !mapstate.has_floor && coord[2] > mapstate.lowest_row
end

"""
Return true IFF the given coordinate is filled with sand or stone.
"""
function isfilled(mapstate::MapState, coord::Tuple{Int,Int})
-        coord in mapstate.filled_blocks
+        (mapstate.has_floor && coord[2] >= mapstate.lowest_row + 2) ||
+            coord in mapstate.filled_blocks
end

"""
@@ -62,12 +65,12 @@ module Maps
"""
Drop a block from (500, 0) until it comes to rest or falls forever.

-    Returns true if the block comes to rest and false if it falls forever.
+    Returns true if the block comes to rest and false if it falls forever or
+    the map is "full". Updates mapstate.
"""
function dropblock!(mapstate::MapState)
coord = (500, 0)
-        while !isfallingforever(mapstate, coord)
+        while !isfallingforever(mapstate, coord) && !isfilled(mapstate, coord)
if !isfilled(mapstate, coord .+ (0, 1))
coord = coord .+ (0, 1)
elseif !isfilled(mapstate, coord .+ (-1, 1))
@@ -83,7 +86,7 @@ module Maps
end

"""
-    Fill the map with sand until all sand will fall forever.
+    Fill the map with sand until all sand will fall forever or the source is filled.

Return the number of blocks that came to rest
"""
@@ -103,6 +106,7 @@ end
@info part_1(input)

function part_2(input)
-    nothing
+    Maps.fillmap!(Maps.MapState(input, true))
end
+@assert part_2(example) == 93
@info part_2(input)
```