Checking in Day 17 even though I haven't figured out part 2 yet. I\'m coming back to it
parent
791d6d9c69
commit
cadb944182
@ -0,0 +1,180 @@
|
|||||||
|
defmodule Day17 do
|
||||||
|
def run do
|
||||||
|
[registers, program] =
|
||||||
|
File.read!("data.txt")
|
||||||
|
|> String.trim()
|
||||||
|
|> String.split("\n\n")
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Enum.map(fn {lines, idx} ->
|
||||||
|
if idx == 0, do: parseRegisters(lines), else: parseProgram(lines)
|
||||||
|
end)
|
||||||
|
|
||||||
|
# registers = %{A: 2024, B: 0, C: 0}
|
||||||
|
# program = [0, 1, 5, 4, 3, 0]
|
||||||
|
|
||||||
|
initial_state = %{
|
||||||
|
program: program,
|
||||||
|
registers: registers,
|
||||||
|
pointer: 0,
|
||||||
|
output: []
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg(initial_state)
|
||||||
|
|
||||||
|
state = run(initial_state)
|
||||||
|
output = Enum.reverse(state.output)
|
||||||
|
dbg(output)
|
||||||
|
|
||||||
|
# part 2
|
||||||
|
# target is [2, 4, 1, 6, 7, 5, 4, 4, 1, 7, 0, 3, 5, 5, 3, 0]
|
||||||
|
# noticing every power of 8 it adds a digit
|
||||||
|
# the new big digit goes [1], 0, 3, 2, 4, 4, 1, 5
|
||||||
|
# when there's 1 digit, the biggest digit changes every 1
|
||||||
|
# when there are 2 digits, the biggest digit changes every 8
|
||||||
|
# when there are 3 digits, the biggest digit changes every 8 * 8
|
||||||
|
# etc.
|
||||||
|
# when there are 16 digits, the biggest digit changes every 8 ^ 15
|
||||||
|
# if the first digit is 2, that's the 3rd in the sequence, so 3x that
|
||||||
|
#
|
||||||
|
# 1 0 3 2 4 4 1 5
|
||||||
|
# when 2 digits, the smaller digit goes:
|
||||||
|
# 0: 1 0 3 2 6 5 1 1
|
||||||
|
# 3: 1 0 2 2 0 6 1 5
|
||||||
|
# 2: 1 0 2 2 2 7 1 1
|
||||||
|
# 4: 1 0 1 3 4 0 1 5
|
||||||
|
# 4: 1 0 1 3 6 1 1 1
|
||||||
|
# 1: 1 0 0 3 0 2 1 5
|
||||||
|
# 5: 1 0 0 3 2 3 1 1
|
||||||
|
#
|
||||||
|
# when 3 digits, smallest digit goes
|
||||||
|
# 0 0 7 0 4 4 1 5
|
||||||
|
#
|
||||||
|
# starter = 3 * 8 ** 15 + 6 * 8 ** 14 + 6 * 8 ** 13 # interesting, all ones
|
||||||
|
starter = 2 * 8 ** 15
|
||||||
|
increment = 8 ** 10
|
||||||
|
|
||||||
|
try(starter, initial_state, increment)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp try(a, state, increment) do
|
||||||
|
# IO.gets("")
|
||||||
|
new_state = %{state | registers: %{state.registers | A: a}}
|
||||||
|
val = run(new_state)
|
||||||
|
|
||||||
|
# if Integer.mod(a, 1000) == 0 do
|
||||||
|
IO.puts(a)
|
||||||
|
dbg(a)
|
||||||
|
dbg(val)
|
||||||
|
# end
|
||||||
|
|
||||||
|
if Enum.reverse(val.output) == state.program do
|
||||||
|
a
|
||||||
|
else
|
||||||
|
try(a + increment, state, increment)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp run(
|
||||||
|
%{
|
||||||
|
program: program,
|
||||||
|
registers: registers,
|
||||||
|
pointer: pointer,
|
||||||
|
output: output
|
||||||
|
} = state
|
||||||
|
) do
|
||||||
|
opcode = Enum.at(program, pointer)
|
||||||
|
operand = Enum.at(program, pointer + 1)
|
||||||
|
# dbg({"run", state})
|
||||||
|
|
||||||
|
if is_nil(opcode) do
|
||||||
|
state
|
||||||
|
else
|
||||||
|
new_state =
|
||||||
|
case opcode do
|
||||||
|
# adv
|
||||||
|
0 ->
|
||||||
|
num = registers[:A]
|
||||||
|
den = Integer.pow(2, getComboOperandValue(operand, registers))
|
||||||
|
new_regs = %{registers | A: trunc(num / den)}
|
||||||
|
|
||||||
|
%{state | registers: new_regs, pointer: pointer + 2}
|
||||||
|
|
||||||
|
# bxl
|
||||||
|
1 ->
|
||||||
|
new_regs = %{registers | B: Bitwise.bxor(registers[:B], operand)}
|
||||||
|
%{state | registers: new_regs, pointer: pointer + 2}
|
||||||
|
|
||||||
|
# bst
|
||||||
|
2 ->
|
||||||
|
new_regs = %{
|
||||||
|
registers
|
||||||
|
| B: Integer.mod(getComboOperandValue(operand, registers), 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
%{state | registers: new_regs, pointer: pointer + 2}
|
||||||
|
|
||||||
|
# jnz
|
||||||
|
3 ->
|
||||||
|
if registers[:A] == 0 do
|
||||||
|
%{state | pointer: pointer + 2}
|
||||||
|
else
|
||||||
|
%{state | pointer: operand}
|
||||||
|
end
|
||||||
|
|
||||||
|
# bxc
|
||||||
|
4 ->
|
||||||
|
new_regs = %{registers | B: Bitwise.bxor(registers[:B], registers[:C])}
|
||||||
|
%{state | registers: new_regs, pointer: pointer + 2}
|
||||||
|
|
||||||
|
# out
|
||||||
|
5 ->
|
||||||
|
val = Integer.mod(getComboOperandValue(operand, registers), 8)
|
||||||
|
%{state | pointer: pointer + 2, output: [val | output]}
|
||||||
|
|
||||||
|
# bdv
|
||||||
|
6 ->
|
||||||
|
num = registers[:A]
|
||||||
|
den = Integer.pow(2, getComboOperandValue(operand, registers))
|
||||||
|
new_regs = %{registers | B: trunc(num / den)}
|
||||||
|
|
||||||
|
%{state | registers: new_regs, pointer: pointer + 2}
|
||||||
|
|
||||||
|
# cdv
|
||||||
|
7 ->
|
||||||
|
num = registers[:A]
|
||||||
|
den = Integer.pow(2, getComboOperandValue(operand, registers))
|
||||||
|
new_regs = %{registers | C: trunc(num / den)}
|
||||||
|
|
||||||
|
%{state | registers: new_regs, pointer: pointer + 2}
|
||||||
|
end
|
||||||
|
|
||||||
|
run(new_state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parseProgram(line) do
|
||||||
|
[_header, digits] = String.split(line, " ")
|
||||||
|
digits |> String.split(",") |> Enum.map(&String.to_integer/1)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp getComboOperandValue(op, registers) do
|
||||||
|
case op do
|
||||||
|
o when o <= 3 -> op
|
||||||
|
4 -> registers[:A]
|
||||||
|
5 -> registers[:B]
|
||||||
|
6 -> registers[:C]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parseRegisters(lines) do
|
||||||
|
lines
|
||||||
|
|> String.split("\n")
|
||||||
|
|> Enum.map(&String.split(&1, " "))
|
||||||
|
|> Enum.reduce(%{}, fn [_header, label, value], acc ->
|
||||||
|
atom = String.trim(label, ":") |> String.to_atom()
|
||||||
|
Map.put(acc, atom, String.to_integer(value))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Day17.run()
|
Loading…
Reference in New Issue