Powered by AppSignal & Oban Pro

Advent of Code 2015 Day 23 Part 2

2015_day23_part2.livemd

Advent of Code 2015 Day 23 Part 2

Mix.install([
  {:kino_aoc, "~> 0.1"}
])

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2015", "23", System.fetch_env!("LB_SESSION"))

My answer

eval_instruction = fn instruction, {a, b, index} ->
  Regex.named_captures(
    ~r/(?<func>[a-z]+) (?<var>[a-z]*),* *(?<offset>(\+|\-)*\d*)/,
    instruction
  )
  |> then(fn %{"func" => func, "var" => var, "offset" => offset} ->
    var = if var == "", do: "a", else: var

    instruction =
      cond do
        offset == "" -> 
          "#{func}.({#{var}, #{index}})"
        func == "jmp" ->
          "#{func}.({a, #{index}}, #{String.to_integer(offset)})"
        true ->
          "#{func}.({#{var}, #{index}}, #{String.to_integer(offset)})"
      end
      |> IO.inspect()

    """
    hlf = fn {a, index} -> {div(a, 2), index + 1} end
    tpl = fn {a, index} -> {a * 3, index + 1} end
    inc = fn {a, index} -> {a + 1, index + 1} end
    jmp = fn {a, index}, offset -> {a, index + offset} end
    jie = fn {a, index}, offset ->
      if rem(a, 2) == 0 do
        {a, index + offset}
      else
        {a, index + 1}
      end
    end
    jio = fn {a, index}, offset ->
      case a do
        1 -> {a, index + offset}
        _ -> {a, index + 1}
      end
    end

    a = #{a}
    b = #{b}

    {#{var}, index} = #{instruction}

    {a, b, index}
    """
  end)
  |> Code.eval_string()
  |> elem(0)
end
instructions = String.split(puzzle_input, "\n")
0..10000
|> Enum.reduce_while({1, 0, 0}, fn _, {a, b, index} ->
  {next_a, next_b, next_index} =
    instructions
    |> Enum.at(index)
    |> eval_instruction.({a, b, index})
    |> IO.inspect()

  if next_index >= length(instructions) do
    {:halt, {next_a, next_b, next_index}}
  else
    {:cont, {next_a, next_b, next_index}}
  end
end)