78 lines
2.1 KiB
Elixir
78 lines
2.1 KiB
Elixir
defmodule AOC.Day8 do
|
|
use AOC.Day, day: 8
|
|
|
|
@start "AAA"
|
|
@stop "ZZZ"
|
|
|
|
def parse_input([instructions, _ | nodes]) do
|
|
instructions = instructions |> String.to_charlist() |> Stream.cycle()
|
|
|
|
nodes =
|
|
Enum.map(nodes, fn s ->
|
|
%{"id" => id, "left" => left, "right" => right} =
|
|
Regex.named_captures(
|
|
~r/^(?<id>[[:alnum:]]{3}) = \((?<left>[[:alnum:]]{3}), (?<right>[[:alnum:]]{3})\)$/,
|
|
s
|
|
)
|
|
|
|
{id, {left, right}}
|
|
end)
|
|
|> Enum.into(%{})
|
|
|
|
{instructions, nodes}
|
|
end
|
|
|
|
def part1({instructions, nodes}) do
|
|
reach_end(instructions, nodes)
|
|
end
|
|
|
|
def part2({instructions, nodes}) do
|
|
IO.puts("Use LCM calculator for the following numbers :)")
|
|
|
|
Enum.filter(nodes, fn {k, _v} -> String.ends_with?(k, "A") end)
|
|
|> Enum.map(fn {k, _v} -> find_cycle(instructions, nodes, k) end)
|
|
|> Enum.map(&elem(&1, 0))
|
|
|> Enum.map(&Integer.to_string/1)
|
|
|> Enum.join(" ")
|
|
end
|
|
|
|
def reach_end(instructions, nodes) do
|
|
Enum.reduce_while(instructions, {@start, 0}, fn instruction, {current_node, step_count} ->
|
|
if current_node == @stop do
|
|
{:halt, step_count}
|
|
else
|
|
{left, right} = Map.fetch!(nodes, current_node)
|
|
|
|
next_node =
|
|
case instruction do
|
|
?L -> left
|
|
?R -> right
|
|
end
|
|
|
|
{:cont, {next_node, step_count + 1}}
|
|
end
|
|
end)
|
|
end
|
|
|
|
def find_cycle(instructions, nodes, start) do
|
|
Enum.reduce_while(instructions, {start, 0, nil}, fn instruction,
|
|
{current_node, step_count, last_end_count} ->
|
|
if String.ends_with?(current_node, "Z") and last_end_count != nil do
|
|
{:halt, {last_end_count, step_count - last_end_count}}
|
|
else
|
|
last_end_count =
|
|
if String.ends_with?(current_node, "Z"), do: step_count, else: last_end_count
|
|
|
|
{left, right} = Map.fetch!(nodes, current_node)
|
|
|
|
next_node =
|
|
case instruction do
|
|
?L -> left
|
|
?R -> right
|
|
end
|
|
|
|
{:cont, {next_node, step_count + 1, last_end_count}}
|
|
end
|
|
end)
|
|
end
|
|
end
|