refactor day15 a bit

Remove need to duplicate first value of pushable_boxes/2
Fail fast when left branch produces :wall in part 2
This commit is contained in:
Adam Millerchip 2024-12-17 09:59:22 +09:00
parent 0825d8db0e
commit 1972ad56ae

View file

@ -78,7 +78,7 @@ defmodule Day15 do
attempt_moves2(next_moves, robot, warehouse)
{:ok, {:box, side}} ->
case get_pushable_boxes2(next, side, move, warehouse, [{next, side}]) do
case get_pushable_boxes2(next, side, move, warehouse) do
:wall ->
attempt_moves2(next_moves, robot, warehouse)
@ -102,8 +102,9 @@ defmodule Day15 do
# [][] []<--make sure RHS moves too
# []
# @<- pushing up pushes all
def get_pushable_boxes2(box, side, move, warehouse, pushable_boxes) do
def get_pushable_boxes2(box, side, move, warehouse, pushable_boxes \\ []) do
next = move.(box)
pushable_boxes = [{box, side} | pushable_boxes]
case abs(elem(next, 1) - elem(box, 1)) do
# horizontal
@ -116,9 +117,7 @@ defmodule Day15 do
:wall
{:ok, {:box, next_side}} ->
get_pushable_boxes2(next, next_side, move, warehouse, [
{next, next_side} | pushable_boxes
])
get_pushable_boxes2(next, next_side, move, warehouse, pushable_boxes)
end
# vertical
@ -154,28 +153,26 @@ defmodule Day15 do
:wall
{{{:ok, {:box, side}}, :error}, left, _right} ->
get_pushable_boxes2(left, side, move, warehouse, [{left, side} | pushable_boxes])
get_pushable_boxes2(left, side, move, warehouse, pushable_boxes)
{{:error, {:ok, {:box, side}}}, _left, right} ->
get_pushable_boxes2(right, side, move, warehouse, [{right, side} | pushable_boxes])
get_pushable_boxes2(right, side, move, warehouse, pushable_boxes)
{{{:ok, {:box, :left}}, {:ok, {:box, :right}}}, left, _} ->
# if left-right, just one box, only need to check one side
# []
# []
get_pushable_boxes2(left, :left, move, warehouse, [{left, :left} | pushable_boxes])
get_pushable_boxes2(left, :left, move, warehouse, pushable_boxes)
{{{:ok, {:box, :right}}, {:ok, {:box, :left}}}, left, right} ->
# if right-left, two boxes, so need to check both...
# [][]
# []
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
with left when left != :wall <- get_pushable_boxes2(left, :right, move, warehouse, []),
right when right != :wall <- get_pushable_boxes2(right, :left, move, warehouse, []) do
pushable_boxes ++ left ++ right
else
:wall -> :wall
end
end
end