Advent of Code 2023 - Day 21
Mix.install([
{:req, "~> 0.4.0"}
])
Input
opts = [headers: [{"cookie", "session=#{System.fetch_env!("LB_AOC_SESSION")}"}]]
puzzle_input = Req.get!("https://adventofcode.com/2023/day/21/input", opts).body
input =
for {row, r} <- String.split(puzzle_input, "\n", trim: true) |> Enum.with_index(1),
{col, c} <- String.graphemes(row) |> Enum.with_index(1),
into: %{},
do: {{r, c}, col}
Part 1
{start, _v} = Enum.find(input, fn {_k, v} -> v == "S" end)
defmodule StepCounter do
def positions_count(init_position, grid, steps) do
{{size, size}, _} = Enum.max(grid)
for _i <- 1..steps, reduce: [init_position] do
acc -> StepCounter.step(acc, grid, size)
end
|> Enum.count()
end
def step(positions, grid, size) do
positions
|> Stream.flat_map(&adjacents/1)
|> Stream.reject(&is_rock?(&1, grid, size))
|> Enum.uniq()
end
defp adjacents({r, c}) do
[
{r + 1, c},
{r - 1, c},
{r, c + 1},
{r, c - 1}
]
end
defp is_rock?({r, c}, grid, size) do
r = Integer.mod(r, size)
c = Integer.mod(c, size)
grid[{r, c}] == "#"
end
end
StepCounter.positions_count(start, input, 64)
Part 2