solve 2024 day 15
This commit is contained in:
parent
4abffd3c5e
commit
d3d86a5b50
3 changed files with 159 additions and 3 deletions
|
@ -4,7 +4,7 @@
|
|||
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
|
||||
| [1] | [2] | [3] | [4] | [5] | [6] | [7] |
|
||||
| [8] | [9] | [10]| [11]| [12]| [13]| [14]|
|
||||
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
|
||||
| [15]| 16 | 17 | 18 | 19 | 20 | 21 |
|
||||
| 22 | 23 | 24 | 25 | | | |
|
||||
|
||||
[1]: ./lib/2024/1.ex
|
||||
|
@ -21,3 +21,4 @@
|
|||
[12]: ./lib/2024/12.ex
|
||||
[13]: ./lib/2024/13.ex
|
||||
[14]: ./lib/2024/14.ex
|
||||
[15]: ./lib/2024/15.ex
|
||||
|
|
155
2024/lib/2024/15.ex
Normal file
155
2024/lib/2024/15.ex
Normal file
|
@ -0,0 +1,155 @@
|
|||
import AOC
|
||||
import AOC.Prelude
|
||||
|
||||
aoc 2024, 15 do
|
||||
def p1(input) do
|
||||
{grid, moves} = read_input(input)
|
||||
|
||||
grid
|
||||
|> apply_moves(moves)
|
||||
|> boxes_coords()
|
||||
|> Enum.map(&gps/1)
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
def p2(input) do
|
||||
{grid, moves} =
|
||||
input
|
||||
|> String.replace("#", "##")
|
||||
|> String.replace("O", "[]")
|
||||
|> String.replace(".", "..")
|
||||
|> String.replace("@", "@.")
|
||||
|> read_input()
|
||||
|
||||
grid
|
||||
|> apply_moves(moves)
|
||||
|> boxes_coords()
|
||||
|> Enum.map(&gps/1)
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
## calculations
|
||||
|
||||
defp boxes_coords(grid) do
|
||||
grid
|
||||
|> Enum.filter(&match?({_, c} when c in ["O", "["], &1))
|
||||
|> Enum.map(&elem(&1, 0))
|
||||
end
|
||||
|
||||
defp gps({x, y}), do: 100 * y + x
|
||||
|
||||
## movement
|
||||
|
||||
defp apply_moves(grid, moves) do
|
||||
Enum.reduce(moves, grid, fn direction, grid ->
|
||||
# it would be more efficient to keep track of this and move it around but
|
||||
# this is much easier to manage
|
||||
robot = find_robot(grid)
|
||||
{_, grid} = apply_move(grid, robot, direction)
|
||||
grid
|
||||
end)
|
||||
end
|
||||
|
||||
defp apply_move(grid, pos, direction, check_pair \\ true) do
|
||||
dest = move(pos, direction)
|
||||
|
||||
case {Map.get(grid, pos), direction, check_pair} do
|
||||
{"#", _, _} ->
|
||||
{:error, grid}
|
||||
|
||||
# should never happen with the way inputs are constructed
|
||||
{nil, _, _} ->
|
||||
{:error, grid}
|
||||
|
||||
{".", _, _} ->
|
||||
{:ok, grid}
|
||||
|
||||
# up and down movements of two-width boxes must be able to move both
|
||||
# chars
|
||||
{char, direction, true} when char in ["[", "]"] and direction in [:up, :down] ->
|
||||
shift =
|
||||
case char do
|
||||
"[" -> :right
|
||||
"]" -> :left
|
||||
end
|
||||
|
||||
with {:ok, grid} <- apply_move(grid, move(pos, shift), direction, false),
|
||||
{:ok, grid} <- apply_move(grid, dest, direction) do
|
||||
grid =
|
||||
grid
|
||||
|> Map.put(dest, char)
|
||||
|> Map.put(pos, ".")
|
||||
|
||||
{:ok, grid}
|
||||
else
|
||||
_ -> {:error, grid}
|
||||
end
|
||||
|
||||
# left and right movements of two-width boxes are no different from
|
||||
# one-width boxes
|
||||
{char, _, _} when char in ["@", "O", "[", "]"] ->
|
||||
with {:ok, grid} <- apply_move(grid, dest, direction) do
|
||||
grid =
|
||||
grid
|
||||
|> Map.put(dest, char)
|
||||
|> Map.put(pos, ".")
|
||||
|
||||
{:ok, grid}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp find_robot(grid) do
|
||||
{pos, "@"} = Enum.find(grid, &match?({_, "@"}, &1))
|
||||
|
||||
pos
|
||||
end
|
||||
|
||||
## traversal
|
||||
|
||||
defp move({x, y}, :up), do: {x, y - 1}
|
||||
defp move({x, y}, :down), do: {x, y + 1}
|
||||
defp move({x, y}, :left), do: {x - 1, y}
|
||||
defp move({x, y}, :right), do: {x + 1, y}
|
||||
|
||||
## input
|
||||
|
||||
defp read_input(input) do
|
||||
[grid_input, moves_input] =
|
||||
String.split(input, "\n\n")
|
||||
|
||||
grid = map_grid(grid_input)
|
||||
|
||||
moves =
|
||||
moves_input
|
||||
|> lines()
|
||||
|> Enum.join()
|
||||
|> String.graphemes()
|
||||
|> Enum.map(fn
|
||||
"^" -> :up
|
||||
"v" -> :down
|
||||
"<" -> :left
|
||||
">" -> :right
|
||||
end)
|
||||
|
||||
{grid, moves}
|
||||
end
|
||||
|
||||
## output
|
||||
|
||||
# defp render(grid) do
|
||||
# {{max_x, _}, _} = Enum.max_by(grid, fn {{x, _}, _} -> x end)
|
||||
# {{_, max_y}, _} = Enum.max_by(grid, fn {{_, y}, _} -> y end)
|
||||
|
||||
# for y <- 0..max_y do
|
||||
# line =
|
||||
# for x <- 0..max_x, into: "" do
|
||||
# Map.get(grid, {x, y})
|
||||
# end
|
||||
|
||||
# IO.puts(line)
|
||||
# end
|
||||
|
||||
# grid
|
||||
# end
|
||||
end
|
|
@ -15,8 +15,8 @@
|
|||
| [2021] | **43/50** 🌟 | Elixir |
|
||||
| [2022] | **14/50** 🌟 | Elixir, Haskell |
|
||||
| [2023] | **19/50** 🌟 | Elixir, Haskell |
|
||||
| [2024] | **28/50** 🌟 | Elixir |
|
||||
| **Total** | **184** 🌟| |
|
||||
| [2024] | **30/50** 🌟 | Elixir |
|
||||
| **Total** | **186** 🌟| |
|
||||
|
||||
[2015]: ./2015
|
||||
[2017]: ./2017
|
||||
|
|
Loading…
Reference in a new issue