Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 8

2023/day8.livemd

Day 8

Mix.install([
  {:kino, "~> 0.11.3"}
])

Section

input = Kino.Input.textarea("Input")
test_data = Kino.Input.read(input)
defmodule Sol8 do
  def add_edge([src, left, right], map) do
    Map.put(map, src, [left, right])
  end

  def get_edge(text) do
    Regex.replace(~r/[=(),]/, text, "") |> String.split()
  end

  def read(text) do
    [cmd, _ | rest] = String.split(text, "\n")
    # edges_str = String.split(rest, "\n")
    [cmd, Enum.reduce(rest, %{}, fn x, acc -> Sol8.add_edge(Sol8.get_edge(x), acc) end)]
  end

  # def go(_, _, "ZZZ", steps) do
  #  steps
  # end

  def go_inf([], _, _, _) do
    0
  end

  def go([cmd | rest], map, loc, steps) do
    if String.ends_with?(loc, "Z") do
      steps
    else
      [left, right] = map[loc]

      case cmd do
        ?L -> Sol8.go(rest, map, left, steps + 1)
        ?R -> Sol8.go(rest, map, right, steps + 1)
      end
    end
  end

  def go_inf([cmd | rest], map, loc, steps) do
    if String.ends_with?(loc, "Z") do
      IO.inspect(steps)
    else
      [left, right] = map[loc]

      case cmd do
        ?L -> Sol8.go_inf(rest, map, left, steps + 1)
        ?R -> Sol8.go_inf(rest, map, right, steps + 1)
      end
    end
  end
end
[cmd, map] = Sol8.read(test_data)
Enum.map(
  ["JQA", "NHA", "AAA", "FSA", "LLA", "MNA"],
  fn x -> Sol8.go_inf(Enum.take(Stream.cycle(String.to_charlist(cmd)), 50000), map, x, 0) end
)
# I found that gcd of any 2 numbers are all the same.
{Integer.gcd(13939, 11309), Integer.gcd(13939, 20777), Integer.gcd(18673, 15517)}
# So it's easy to get LCM of the 6 numbers
Enum.reduce(
  [13939, 11309, 20777, 15517, 17621, 18673],
  1,
  fn x, acc -> acc * x / 263 end
) * 263