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] |
|
| [1] | [2] | [3] | [4] | [5] | [6] | [7] |
|
||||||
| [8] | [9] | [10]| [11]| [12]| [13]| [14]|
|
| [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 | | | |
|
| 22 | 23 | 24 | 25 | | | |
|
||||||
|
|
||||||
[1]: ./lib/2024/1.ex
|
[1]: ./lib/2024/1.ex
|
||||||
|
@ -21,3 +21,4 @@
|
||||||
[12]: ./lib/2024/12.ex
|
[12]: ./lib/2024/12.ex
|
||||||
[13]: ./lib/2024/13.ex
|
[13]: ./lib/2024/13.ex
|
||||||
[14]: ./lib/2024/14.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 |
|
| [2021] | **43/50** 🌟 | Elixir |
|
||||||
| [2022] | **14/50** 🌟 | Elixir, Haskell |
|
| [2022] | **14/50** 🌟 | Elixir, Haskell |
|
||||||
| [2023] | **19/50** 🌟 | Elixir, Haskell |
|
| [2023] | **19/50** 🌟 | Elixir, Haskell |
|
||||||
| [2024] | **28/50** 🌟 | Elixir |
|
| [2024] | **30/50** 🌟 | Elixir |
|
||||||
| **Total** | **184** 🌟| |
|
| **Total** | **186** 🌟| |
|
||||||
|
|
||||||
[2015]: ./2015
|
[2015]: ./2015
|
||||||
[2017]: ./2017
|
[2017]: ./2017
|
||||||
|
|
Loading…
Reference in a new issue