Advent of Code 2024 - Day 17
Mix.install([
{:kino_aoc, "~> 0.1.7"}
])
Section
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "17", System.fetch_env!("LB_AOC_SESSION"))
IO.puts(puzzle_input)
input_lines =
puzzle_input
|> String.split("\n")
ax = input_lines |> Enum.at(0) |> String.split() |> Enum.at(2) |> String.to_integer()
bx = input_lines |> Enum.at(1) |> String.split() |> Enum.at(2) |> String.to_integer()
cx = input_lines |> Enum.at(2) |> String.split() |> Enum.at(2) |> String.to_integer()
program =
input_lines
|> Enum.at(-1)
|> String.split()
|> Enum.at(-1)
|> String.split(",")
|> Enum.map(&String.to_integer/1)
|> List.to_tuple()
-
B = a
-
B = B ^ 1
-
C = A >> B
-
B = B ^ 5
-
B = B ^ C
-
print b
-
A = A >> 3
-
start over again if
A != 0
defmodule Computer do
@compile :inline
import Bitwise
@adv 0
@bxl 1
@bst 2
@jnz 3
@bxc 4
@out 5
@bdv 6
@cdv 7
@mask (1 <<< 32) - 1
def run(program, ax, bx, cx) do
context = %{
program: program,
cursor: 0,
ax: ax,
bx: bx,
cx: cx,
output: []
}
context
|> Stream.iterate(&eval/1)
|> Enum.find(fn context ->
context.cursor >= tuple_size(program) - 1
end)
|> Map.get(:output)
|> Enum.reverse()
|> List.to_tuple()
end
defp eval(context) do
instruction = elem(context.program, context.cursor)
operand = elem(context.program, context.cursor + 1)
eval_instruction(instruction, operand, context)
end
defp eval_instruction(@adv, n, context) do
quotient = context.ax >>> combo(n, context)
%{context | ax: quotient, cursor: context.cursor + 2}
end
defp eval_instruction(@bxl, n, context) do
%{context | bx: bxor(context.bx, n) &&& @mask, cursor: context.cursor + 2}
end
defp eval_instruction(@bst, n, context) do
%{context | bx: combo(n, context) &&& 7, cursor: context.cursor + 2}
end
defp eval_instruction(@jnz, n, context) do
if context.ax == 0 do
%{context | cursor: context.cursor + 2}
else
%{context | cursor: n}
end
end
defp eval_instruction(@bxc, _n, context) do
%{context | bx: bxor(context.bx, context.cx), cursor: context.cursor + 2}
end
defp eval_instruction(@out, n, context) do
%{context | output: [combo(n, context) &&& 7 | context.output], cursor: context.cursor + 2}
end
defp eval_instruction(@bdv, n, context) do
quotient = context.ax >>> combo(n, context)
%{context | bx: quotient, cursor: context.cursor + 2}
end
defp eval_instruction(@cdv, n, context) do
quotient = context.ax >>> combo(n, context)
%{context | cx: quotient, cursor: context.cursor + 2}
end
defp combo(4, context) do
context.ax
end
defp combo(5, context) do
context.bx
end
defp combo(6, context) do
context.cx
end
defp combo(7, _context) do
raise RuntimeError, "Not implemented"
end
defp combo(n, _context) when n <= 3 do
n
end
end
Computer.run(program, ax, bx, cx)
out = a ^ 4 ^ ((A >> (a ^ 1)) & 7)
((A >> (a ^ 1)) & 7) ^ a ^ 4 = output
defmodule AoC2024.Day17.Part2 do
import Bitwise
def crack(program) do
program
|> Tuple.to_list()
|> Enum.reverse()
|> crack(0, 0)
end
def crack([h | t], a, acc) do
acc2 = acc |> bsl(3) |> bor(a)
p =
acc2
|> bsr(bxor(a, 1))
|> band(7)
|> bxor(a)
|> bxor(4)
cond do
p != h and a < 7 ->
crack([h | t], a + 1, acc)
p != h ->
false
result = crack(t, 0, acc2) ->
result
a < 7 ->
crack([h | t], a + 1, acc)
true ->
false
end
end
def crack([], _a, acc) do
acc
end
end
cracked = AoC2024.Day17.Part2.crack(program)
Computer.run(program, cracked, 0, 0) == program