defmodule Aoc2023.Day8 do require Integer use Aoc2023 def parse(input) do input |> String.split("\n\n") |> then(fn [directions, map] -> { directions |> String.to_charlist() |> Enum.map(&%{?L => 0, ?R => 1}[&1]), map |> lines |> Enum.map(&Regex.run(~r/(\w+) = \((\w+), (\w+)\)/, &1, capture: :all_but_first)) |> Enum.map(fn [src, dst1, dst2] -> {src, {dst1, dst2}} end) |> Enum.into(%{}) } end) end defp run({directions, map}, node, filter) do directions |> Stream.cycle() |> Stream.scan(node, fn dir, pos -> map[pos] |> elem(dir) end) |> Enum.find_index(filter) |> Kernel.+(1) end def part1({directions, map}) do if map["AAA"], do: run({directions, map}, "AAA", &(&1 == "ZZZ")) end def part2({directions, map}) do map |> Enum.map(pipe(elem(0))) |> Enum.filter(pipe(String.ends_with?("A"))) |> Enum.map(&run({directions, map}, &1, pipe(String.ends_with?("Z")))) |> lcm end end