95 lines
1.7 KiB
Markdown
95 lines
1.7 KiB
Markdown
# AOC 2024 Day 11
|
|
|
|
## Section
|
|
|
|
```elixir
|
|
input = """
|
|
""" |> String.trim()
|
|
|
|
```
|
|
|
|
```elixir
|
|
defmodule Blink do
|
|
def blink(stones) do
|
|
blink(stones |> Map.to_list(), %{})
|
|
end
|
|
|
|
def blink([], acc), do: acc
|
|
|
|
def blink([{0, n} | rest], acc) do
|
|
blink(rest, acc |> Map.update(1, n, &(&1 + n)))
|
|
end
|
|
|
|
def blink([{stone, n} | rest], acc) do
|
|
case even_digits?(stone) do
|
|
{true, x} ->
|
|
left = left(stone, div(x, 2))
|
|
right = stone - shift_left(left, div(x, 2))
|
|
|
|
blink(
|
|
rest,
|
|
acc
|
|
|> Map.update(left, n, &(&1 + n))
|
|
|> Map.update(right, n, &(&1 + n))
|
|
)
|
|
|
|
_ ->
|
|
blink(
|
|
rest,
|
|
acc |> Map.update(stone * 2024, n, &(&1 + n))
|
|
)
|
|
end
|
|
end
|
|
|
|
def split_n(n, m) do
|
|
{left(n, m), right(n, m)}
|
|
end
|
|
|
|
def left(n, 0), do: n
|
|
|
|
def left(n, m) do
|
|
left(div(n, 10), m - 1)
|
|
end
|
|
|
|
def right(n, m) do
|
|
left = left(n, m)
|
|
right = n - shift_left(left, m)
|
|
right
|
|
end
|
|
|
|
def shift_left(n, 0), do: n
|
|
|
|
def shift_left(n, m) do
|
|
shift_left(n * 10, m - 1)
|
|
end
|
|
|
|
def even_digits?(0), do: {false, 1}
|
|
|
|
def even_digits?(n) do
|
|
even_digits?(n, 0)
|
|
end
|
|
|
|
def even_digits?(0, a), do: {rem(a, 2) == 0, a}
|
|
def even_digits?(n, a), do: even_digits?(div(n, 10), a + 1)
|
|
|
|
def solve(input, n) do
|
|
input = input |> String.split(" ") |> Enum.map(&String.to_integer/1) |> Enum.frequencies()
|
|
for _ <- 1..n, reduce: input do
|
|
acc -> Blink.blink(acc)
|
|
end
|
|
|> Map.values()
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def part1(input), do: solve(input, 25)
|
|
def part2(input), do: solve(input, 75)
|
|
end
|
|
```
|
|
|
|
```elixir
|
|
Blink.part1(input)
|
|
```
|
|
|
|
```elixir
|
|
Blink.part2(input)
|
|
```
|