1
0
Fork 0
advent-of-code/2023/lib/2023/8.ex
2023-12-08 12:49:55 -05:00

75 lines
1.5 KiB
Elixir

import AOC
import AOCHelpers
aoc 2023, 8 do
def p1(input) do
{instructions, mappings} = read_input(input)
all_but_last_step =
instructions
|> Stream.cycle()
|> Stream.scan("AAA", &step(&1, &2, mappings))
|> Stream.take_while(&(&1 != "ZZZ"))
|> Enum.count()
all_but_last_step + 1
end
def p2(input) do
{instructions, mappings} = read_input(input)
starts =
mappings
|> Map.keys()
|> Enum.filter(&String.ends_with?(&1, "A"))
lengths =
starts
|> Enum.map(fn start ->
n =
instructions
|> Stream.cycle()
|> Stream.scan(start, &step(&1, &2, mappings))
|> Stream.take_while(&(not String.ends_with?(&1, "Z")))
|> Enum.count()
n + 1
end)
Enum.reduce(lengths, fn a, b ->
div(a * b, Integer.gcd(a, b))
end)
end
def step("L", curr, mappings) do
mappings
|> Map.get(curr)
|> elem(0)
end
def step("R", curr, mappings) do
mappings
|> Map.get(curr)
|> elem(1)
end
def step_all(inst, currs, mappings) do
Enum.map(currs, &step(inst, &1, mappings))
end
def read_input(input) do
[instructions_string, _ | mapping_lines] = lines(input)
instructions = letters(instructions_string)
mappings =
mapping_lines
|> Enum.map(fn mapping_line ->
[_, key, left, right] = Regex.run(~r/^(.+) = \((.+), (.+)\)$/, mapping_line)
{key, {left, right}}
end)
|> Enum.into(%{})
{instructions, mappings}
end
end