This commit is contained in:
parent
4dcdab9931
commit
11e32ddfda
@ -11,7 +11,7 @@ def combo(registers: dict[str, int], operand: int):
|
||||
|
||||
|
||||
def adv(registers: dict[str, int], operand: int) -> int | None:
|
||||
registers["A"] = registers["A"] // (2 ** combo(registers, operand))
|
||||
registers["A"] = registers["A"] >> combo(registers, operand)
|
||||
|
||||
|
||||
def bxl(registers: dict[str, int], operand: int) -> int | None:
|
||||
@ -32,11 +32,11 @@ def bxc(registers: dict[str, int], operand: int) -> int | None:
|
||||
|
||||
|
||||
def bdv(registers: dict[str, int], operand: int) -> int | None:
|
||||
registers["B"] = registers["A"] // (2 ** combo(registers, operand))
|
||||
registers["B"] = registers["A"] >> combo(registers, operand)
|
||||
|
||||
|
||||
def cdv(registers: dict[str, int], operand: int) -> int | None:
|
||||
registers["C"] = registers["A"] // (2 ** combo(registers, operand))
|
||||
registers["C"] = registers["A"] >> combo(registers, operand)
|
||||
|
||||
|
||||
def run(registers: dict[str, int], program: list[int]):
|
||||
@ -47,30 +47,6 @@ def run(registers: dict[str, int], program: list[int]):
|
||||
|
||||
instructions = [adv, bxl, bst, jnz, bxc, out, bdv, cdv]
|
||||
|
||||
u = {
|
||||
adv: "A = A // (2 ** {})",
|
||||
bxl: "B = B ^ {}",
|
||||
bst: "B = {} % 8",
|
||||
jnz: "JMP {}",
|
||||
bxc: "B = B ^ C",
|
||||
out: "OUT {}",
|
||||
bdv: "B = A // (2 ** {})",
|
||||
cdv: "C = A // (2 ** {})",
|
||||
}
|
||||
|
||||
for index in range(0, len(program), 2):
|
||||
print(
|
||||
u[instructions[program[index]]].format(
|
||||
""
|
||||
if program[index] == 4
|
||||
else (
|
||||
program[index + 1]
|
||||
if program[index] in (1, 3) or program[index + 1] < 4
|
||||
else "ABC"[program[index + 1] - 4]
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
index = 0
|
||||
while index < len(program):
|
||||
instruction, operand = instructions[program[index]], program[index + 1]
|
||||
@ -96,12 +72,37 @@ class Solver(BaseSolver):
|
||||
}
|
||||
program = [int(c) for c in program_s.split(":")[1].strip().split(",")]
|
||||
|
||||
print(f"program ({len(program)}):", ",".join(map(str, program)))
|
||||
self.logger.info(f"program ({len(program)}): " + ",".join(map(str, program)))
|
||||
|
||||
instruction_s = [
|
||||
"A = A >> {}",
|
||||
"B = B ^ {}",
|
||||
"B = {} % 8",
|
||||
"JMP {}",
|
||||
"B = B ^ C",
|
||||
"OUT {} % 8",
|
||||
"B = A >> {}",
|
||||
"C = A >> {}",
|
||||
]
|
||||
|
||||
self.logger.info("PROGRAM:")
|
||||
for index in range(0, len(program), 2):
|
||||
self.logger.info(
|
||||
instruction_s[program[index]].format(
|
||||
""
|
||||
if program[index] == 4
|
||||
else (
|
||||
program[index + 1]
|
||||
if program[index] in (1, 3) or program[index + 1] < 4
|
||||
else "ABC"[program[index + 1] - 4]
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
yield ",".join(map(str, run(registers.copy(), program)))
|
||||
|
||||
out_index = next(i for i in range(0, len(program), 2) if program[i] == 5)
|
||||
out_register = "ABC"[program[out_index + 1] - 4]
|
||||
# out_index = next(i for i in range(0, len(program), 2) if program[i] == 5)
|
||||
# out_register = "ABC"[program[out_index + 1] - 4]
|
||||
|
||||
# there is only one jump instruction and it goes back to the beginning of the
|
||||
# program
|
||||
@ -112,5 +113,18 @@ class Solver(BaseSolver):
|
||||
and program[-1] == 0
|
||||
)
|
||||
|
||||
for value in program:
|
||||
print(value, f"{out_register} must equal {value | 4}")
|
||||
valid: list[int] = [0]
|
||||
for p in reversed(program):
|
||||
new_valid: list[int] = []
|
||||
for v in valid:
|
||||
a_high = v << 3
|
||||
for a_low in range(0, 2**3):
|
||||
a = a_high | a_low
|
||||
b = (((a % 8) ^ 7) ^ (a >> ((a % 8) ^ 7))) ^ 4
|
||||
if b % 8 == p:
|
||||
new_valid.append(a)
|
||||
valid = new_valid
|
||||
|
||||
assert run(registers | {"A": min(valid)}, program) == program
|
||||
|
||||
yield min(valid)
|
||||
|
Loading…
Reference in New Issue
Block a user