From 11e32ddfdacff408bb4808015cc6a9d4c1efb74a Mon Sep 17 00:00:00 2001 From: Mikael CAPELLE Date: Tue, 17 Dec 2024 14:28:37 +0100 Subject: [PATCH] 2024 day 17 specific to me. --- src/holt59/aoc/2024/day17.py | 78 +++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/holt59/aoc/2024/day17.py b/src/holt59/aoc/2024/day17.py index cdf4b0a..5806513 100644 --- a/src/holt59/aoc/2024/day17.py +++ b/src/holt59/aoc/2024/day17.py @@ -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)