2024 Day 15 Part 2 😵
This commit is contained in:
parent
4937115328
commit
42911c032d
1 changed files with 173 additions and 2 deletions
175
2024/day15.exs
175
2024/day15.exs
|
@ -47,8 +47,179 @@ defmodule Day15 do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def part2(_input) do
|
def part2({warehouse, {x, y}, moves}) do
|
||||||
:boring_skipped
|
bigger_warehouse =
|
||||||
|
Enum.reduce(warehouse, %{}, fn {{x, y}, v}, bigger ->
|
||||||
|
{left, right} =
|
||||||
|
case v do
|
||||||
|
:box -> {{:box, :left}, {:box, :right}}
|
||||||
|
:wall -> {:wall, :wall}
|
||||||
|
end
|
||||||
|
|
||||||
|
bigger |> Map.put({x * 2, y}, left) |> Map.put({x * 2 + 1, y}, right)
|
||||||
|
end)
|
||||||
|
|
||||||
|
robot = {x * 2, y}
|
||||||
|
|
||||||
|
warehouse = attempt_moves2(moves, robot, bigger_warehouse)
|
||||||
|
# dbg(Enum.filter(warehouse, &match?({_, {:box, _}}, &1)))
|
||||||
|
|
||||||
|
warehouse
|
||||||
|
|> Enum.map(fn
|
||||||
|
{{x, y}, {:box, :left}} -> x + y * 100
|
||||||
|
_ -> 0
|
||||||
|
end)
|
||||||
|
|> Enum.sum()
|
||||||
|
end
|
||||||
|
|
||||||
|
def attempt_moves2([], robot, warehouse) do
|
||||||
|
# dbg(robot)
|
||||||
|
warehouse
|
||||||
|
end
|
||||||
|
|
||||||
|
def attempt_moves2([move | next_moves], robot, warehouse) do
|
||||||
|
warehouse = Map.put(warehouse, robot, :robot)
|
||||||
|
|
||||||
|
# for y <- 0..19 do
|
||||||
|
# for x <- 0..19 do
|
||||||
|
# case Map.fetch(warehouse, {x, y}) do
|
||||||
|
# :error -> IO.write(" ")
|
||||||
|
# {:ok, :wall} -> IO.write("#")
|
||||||
|
# {:ok, {:box, :left}} -> IO.write("[")
|
||||||
|
# {:ok, {:box, :right}} -> IO.write("]")
|
||||||
|
# {:ok, :robot} -> IO.write("@")
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# IO.write("\n")
|
||||||
|
# end
|
||||||
|
|
||||||
|
warehouse = Map.delete(warehouse, robot)
|
||||||
|
|
||||||
|
# IO.gets("next?")
|
||||||
|
|
||||||
|
next = move.(robot)
|
||||||
|
# dbg(Enum.filter(warehouse, &match?({_, {:box, _}}, &1)))
|
||||||
|
|
||||||
|
case Map.fetch(warehouse, next) do
|
||||||
|
:error ->
|
||||||
|
attempt_moves2(next_moves, next, warehouse)
|
||||||
|
|
||||||
|
{:ok, :wall} ->
|
||||||
|
attempt_moves2(next_moves, robot, warehouse)
|
||||||
|
|
||||||
|
{:ok, {:box, side}} ->
|
||||||
|
case get_pushable_boxes2(next, side, move, warehouse, [{next, side}]) do
|
||||||
|
:wall ->
|
||||||
|
attempt_moves2(next_moves, robot, warehouse)
|
||||||
|
|
||||||
|
boxes ->
|
||||||
|
# IO.puts("moving boxes...")
|
||||||
|
# dbg(boxes)
|
||||||
|
|
||||||
|
new_boxes = Map.new(boxes, fn {box, side} -> {move.(box), {:box, side}} end)
|
||||||
|
|
||||||
|
warehouse =
|
||||||
|
warehouse
|
||||||
|
|> Map.drop(Enum.map(boxes, &elem(&1, 0)))
|
||||||
|
|> Map.merge(new_boxes)
|
||||||
|
|
||||||
|
attempt_moves2(next_moves, next, warehouse)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# need to account for 2-width boxes when pushing vertically
|
||||||
|
# @<--pushing down moves down all RHS of stack
|
||||||
|
# [][][][]
|
||||||
|
# [][][] @
|
||||||
|
# [][] []<--make sure RHS moves too
|
||||||
|
# []
|
||||||
|
# @<- pushing up pushes all
|
||||||
|
def get_pushable_boxes2(box, side, move, warehouse, pushable_boxes) do
|
||||||
|
next = move.(box)
|
||||||
|
|
||||||
|
# IO.puts("trying to push #{inspect(box)} (#{side}) to #{inspect(next)}")
|
||||||
|
|
||||||
|
case abs(elem(next, 1) - elem(box, 1)) do
|
||||||
|
# horizontal
|
||||||
|
0 ->
|
||||||
|
case Map.fetch(warehouse, next) do
|
||||||
|
:error ->
|
||||||
|
pushable_boxes
|
||||||
|
|
||||||
|
{:ok, :wall} ->
|
||||||
|
:wall
|
||||||
|
|
||||||
|
{:ok, {:box, next_side}} ->
|
||||||
|
get_pushable_boxes2(next, next_side, move, warehouse, [
|
||||||
|
{next, next_side} | pushable_boxes
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
# vertical
|
||||||
|
1 ->
|
||||||
|
{x, y} = box
|
||||||
|
|
||||||
|
{other_box, other_side} =
|
||||||
|
case side do
|
||||||
|
:left -> {{x + 1, y}, :right}
|
||||||
|
:right -> {{x - 1, y}, :left}
|
||||||
|
end
|
||||||
|
|
||||||
|
other_next = move.(other_box)
|
||||||
|
# IO.puts("bringing #{inspect(other_box)} (#{other_side}) too")
|
||||||
|
|
||||||
|
pushable_boxes = [{other_box, other_side} | pushable_boxes]
|
||||||
|
|
||||||
|
side
|
||||||
|
|> case do
|
||||||
|
:left ->
|
||||||
|
# IO.puts("checking #{inspect(next)}, #{inspect(other_next)}")
|
||||||
|
{{Map.fetch(warehouse, next), Map.fetch(warehouse, other_next)}, next, other_next}
|
||||||
|
|
||||||
|
:right ->
|
||||||
|
# IO.puts("checking #{inspect(other_next)}, #{inspect(next)}")
|
||||||
|
{{Map.fetch(warehouse, other_next), Map.fetch(warehouse, next)}, other_next, next}
|
||||||
|
end
|
||||||
|
|> case do
|
||||||
|
{{:error, :error}, _, _} ->
|
||||||
|
pushable_boxes
|
||||||
|
|
||||||
|
{{{:ok, :wall}, _}, _, _} ->
|
||||||
|
:wall
|
||||||
|
|
||||||
|
{{_, {:ok, :wall}}, _, _} ->
|
||||||
|
:wall
|
||||||
|
|
||||||
|
{{{:ok, {:box, side}}, :error}, left, _right} ->
|
||||||
|
get_pushable_boxes2(left, side, move, warehouse, [{left, side} | pushable_boxes])
|
||||||
|
|
||||||
|
{{:error, {:ok, {:box, side}}}, _left, right} ->
|
||||||
|
get_pushable_boxes2(right, side, move, warehouse, [{right, side} | pushable_boxes])
|
||||||
|
|
||||||
|
{{{:ok, {:box, :left}}, {:ok, {:box, :right}}}, left, _} ->
|
||||||
|
# if left-right, just one box, only need to check one side
|
||||||
|
# []
|
||||||
|
# []
|
||||||
|
IO.puts("box is straight above")
|
||||||
|
get_pushable_boxes2(left, :left, move, warehouse, [{left, :left} | pushable_boxes])
|
||||||
|
|
||||||
|
{{{:ok, {:box, :right}}, {:ok, {:box, :left}}}, left, right} ->
|
||||||
|
# if right-left, two boxes, so need to check both...
|
||||||
|
# [][]
|
||||||
|
# []
|
||||||
|
IO.puts("two boxes above")
|
||||||
|
left = get_pushable_boxes2(left, :right, move, warehouse, [{left, :right}])
|
||||||
|
right = get_pushable_boxes2(right, :left, move, warehouse, [{right, :left}])
|
||||||
|
|
||||||
|
if left == :wall or right == :wall do
|
||||||
|
:wall
|
||||||
|
else
|
||||||
|
pushable_boxes ++ left ++ right
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def input do
|
def input do
|
||||||
|
|
Loading…
Add table
Reference in a new issue