diff --git a/2024/day15.exs b/2024/day15.exs index b5dad91..b6c332c 100755 --- a/2024/day15.exs +++ b/2024/day15.exs @@ -20,7 +20,7 @@ defmodule Day15 do attempt_moves(next_moves, robot, warehouse) {:ok, :box} -> - case get_pushable_boxes(next, move, warehouse, [next]) do + case get_pushable_boxes(next, move, warehouse) do :wall -> attempt_moves(next_moves, robot, warehouse) @@ -35,13 +35,14 @@ defmodule Day15 do end end - def get_pushable_boxes(box, move, warehouse, pushable_boxes) do + def get_pushable_boxes(box, move, warehouse, pushable_boxes \\ []) do next = move.(box) + pushable_boxes = [box | pushable_boxes] case Map.fetch(warehouse, next) do :error -> pushable_boxes {:ok, :wall} -> :wall - {:ok, :box} -> get_pushable_boxes(next, move, warehouse, [next | pushable_boxes]) + {:ok, :box} -> get_pushable_boxes(next, move, warehouse, pushable_boxes) end end @@ -78,7 +79,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 +103,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 +118,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,27 +154,23 @@ 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 end end