diff --git a/day17.py b/day17.py index 20edc9c..13849b2 100644 --- a/day17.py +++ b/day17.py @@ -87,14 +87,14 @@ class Computer: def out(self, operand: int) -> None: value = self.get_combo_value(operand) % 8 - self.output.append(value) if not self.check_output: self.instr_pointer += 1 - elif value != self.__code[len(self.output) - 1]: - # print(f"Want to add {value} to {self.output=}, but expected {self.__code[len(self.output) - 1]}") + self.output.append(value) + elif value != self.__code[len(self.output)]: self.instr_pointer = len(self.code) else: self.instr_pointer += 1 + self.output.append(value) def bdv(self, operand: int) -> None: self.reg_b = self.reg_a // (2 ** self.get_combo_value(operand)) @@ -124,6 +124,7 @@ class Day(AOCDay): [ (117440, "input17_test2"), (202356708354602, "input17_neil"), + (236555995274861, "input17_dennis"), (None, "input17"), ], ] @@ -142,46 +143,54 @@ class Day(AOCDay): expected_output = ",".join(str(x) for x in prog) computer = Computer(a, b, c, prog) computer.check_output = True - print(computer.code) + + def run_computer(v: int) -> str: + computer.reset() + computer.reg_a = v + computer.run_code() + return computer.get_output() init_a = 0 + init_reg = 0 output = "" + bit_match = "" + bit_width = 6 + bit_add = bit_width - 1 factor = 0 additive = 0 + best = 0 while output != expected_output: - computer.reset() - init_reg = init_a * (8 ** factor) + additive - if init_reg > 8 ** 16: - print("FAIL! AGAIN!") - break - computer.reg_a = init_reg - computer.run_code() - output = computer.get_output() - if len(output) > factor + 1 and output == expected_output[:len(output)]: - print(init_a, init_reg, output, expected_output) - additive = (int(bin(init_reg)[-6:], 2) << (3 * factor)) | additive - #additive += int(bin(init_reg)[-6:], 2) - factor += 2 + init_reg = init_a * (8**factor) + additive + output = run_computer(init_reg) - if len(output) > 3 and output == expected_output[:len(output)]: - print(f"{init_a=}, {factor=}, {additive=}, {output=}, {expected_output=}") + if len(output) > best and output == expected_output[: len(output)]: + # if output == expected_output[: len(output)]: + o = oct(init_reg) + if o[-bit_width:] != bit_match: + bit_match = o[-bit_width:] + else: + additive = int(bit_match, 8) + factor = bit_width + bit_width += bit_add + bit_add -= 1 + init_a = 0 + + print( + f"{init_reg=} ({oct(init_reg)}), {factor=}, additive={oct(additive)}, {output=}, {expected_output=}" + ) + best = len(output) if init_a % 1_000_000 == 0: print(init_a, init_reg) init_a += 1 - print(init_a - 1, (init_a - 1) * (8 ** factor) + additive) - computer.reset() - computer.reg_a = init_a - 1 - computer.run_code() - print(computer.get_output()) - if computer.get_output() == expected_output: - return init_a - 1 + print(init_a - 1, (init_a - 1) * (8**factor) + additive) + output = run_computer(init_reg) + print(output) + if output == expected_output: + return init_reg return "" - - - first = [] for i, c in enumerate(prog): reg_a_init = 0 @@ -200,7 +209,7 @@ class Day(AOCDay): for i, c in enumerate(reversed(first)): result = result << 3 result += c // 8 - #result = sum(((x * (8 ** i) for i, x in enumerate(first)))) + # result = sum(((x * (8 ** i) for i, x in enumerate(first)))) print(result) computer.reset() @@ -219,8 +228,8 @@ class Day(AOCDay): return result for i in range(len(first)): - result = sum(((x * (8 ** i) for i, x in enumerate(first[:i + 1])))) - print("Testing ", first[:i + 1], "=", result) + result = sum(((x * (8**i) for i, x in enumerate(first[: i + 1])))) + print("Testing ", first[: i + 1], "=", result) computer.reset() computer.reg_a = result computer.run_code() diff --git a/inputs/input17_dennis b/inputs/input17_dennis new file mode 100644 index 0000000..cb1b0c7 --- /dev/null +++ b/inputs/input17_dennis @@ -0,0 +1,5 @@ +Register A: 30118712 +Register B: 0 +Register C: 0 + +Program: 2,4,1,3,7,5,4,2,0,3,1,5,5,5,3,0 \ No newline at end of file