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

Advent of code day 17

2024/livebooks/day-17.livemd

Advent of code day 17

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

Setup input

example = Kino.Input.textarea("Please paste your input example:")
input = Kino.Input.textarea("Please paste your real input:")

Part 01

import Bitwise

[a, b, c | program] =
  Regex.scan(~r/\d+/, Kino.Input.read(example))
  |> Enum.map(fn [x | _] -> String.to_integer(x) end)

0
|> Stream.iterate(&(&1 + 1))
|> Enum.reduce_while({a, b, c, program, 0, []}, fn _, {a, b, c, program, idx, output} ->
  combo = fn op ->
    case op do
      op when op <= 3 -> op
      4 -> a
      5 -> b
      6 -> c
    end
  end

  if idx >= length(program) do
    {:halt, output}
  else
    ins = Enum.at(program, idx)
    operand = Enum.at(program, idx + 1)

    case ins do
      0 ->
        a = a >>> combo.(operand)
        {:cont, {a, b, c, program, idx + 2, output}}

      1 ->
        b = Bitwise.bxor(b, operand)
        {:cont, {a, b, c, program, idx + 2, output}}

      2 ->
        b = Integer.mod(combo.(operand), 8)
        {:cont, {a, b, c, program, idx + 2, output}}

      3 when a != 0 ->
        idx = operand
        {:cont, {a, b, c, program, idx, output}}

      3 ->
        {:cont, {a, b, c, program, idx + 2, output}}

      4 ->
        b = Bitwise.bxor(b, c)
        {:cont, {a, b, c, program, idx + 2, output}}

      5 ->
        output = output ++ [Integer.mod(combo.(operand), 8)]
        {:cont, {a, b, c, program, idx + 2, output}}

      6 ->
        b = div(a, 2 ** combo.(operand))
        {:cont, {a, b, c, program, idx + 2, output}}

      7 ->
        c = a >>> combo.(operand)
        {:cont, {a, b, c, program, idx + 2, output}}
    end
  end
end)
|> Enum.join(",")

Part 02