Powered by AppSignal & Oban Pro

Advent of Code 2015 Day 23 Part 1

2015_day23_part1.livemd

Advent of Code 2015 Day 23 Part 1

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

Get Inputs

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

My answer

instructions =
  """
  inc a
  jio a, +2
  tpl a
  inc a
  """
  |> String.trim()
  |> String.split("\n")
eval_instruction = fn instruction, {a, b, index} ->
  Regex.named_captures(
    ~r/(?[a-z]+) (?[a-z]*),* *(?(\+|\-)*\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
eval_instruction.("hlf a", {4, 6, 0})
eval_instruction.("hlf b", {4, 6, 0})
eval_instruction.("tpl a", {1, 1, 0})
eval_instruction.("inc a", {0, 1, 0})
eval_instruction.("jmp 5", {0, 1, 0})
eval_instruction.("jmp -5", {0, 1, 10})
eval_instruction.("jie a, 3", {2, 1, 0})
eval_instruction.("jie a, 3", {3, 1, 0})
eval_instruction.("jio a, 3", {1, 1, 0})
eval_instruction.("jio a, 3", {2, 1, 0})
0..10
|> Enum.reduce_while({0, 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) - 1 do
    {:halt, {next_a, next_b, next_index}}
  else
    {:cont, {next_a, next_b, next_index}}
  end
end)
instructions = String.split(puzzle_input, "\n")
0..1000
|> Enum.reduce_while({0, 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)