generated from public/aoc_template
Compare commits
2 Commits
c4066aaac6
...
e9dc91a4b1
| Author | SHA1 | Date | |
|---|---|---|---|
| e9dc91a4b1 | |||
| 161bd10ca3 |
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 8.6 KiB |
BIN
.aoc_tiles/tiles/2024/18.png
Normal file
BIN
.aoc_tiles/tiles/2024/18.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<!-- AOC TILES BEGIN -->
|
<!-- AOC TILES BEGIN -->
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
2024 - 33 ⭐ - Python
|
2024 - 36 ⭐ - Python
|
||||||
</h1>
|
</h1>
|
||||||
<a href="day01.py">
|
<a href="day01.py">
|
||||||
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
|
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
|
||||||
@ -55,4 +55,7 @@
|
|||||||
<a href="day17.py">
|
<a href="day17.py">
|
||||||
<img src=".aoc_tiles/tiles/2024/17.png" width="161px">
|
<img src=".aoc_tiles/tiles/2024/17.png" width="161px">
|
||||||
</a>
|
</a>
|
||||||
|
<a href="day18.py">
|
||||||
|
<img src=".aoc_tiles/tiles/2024/18.png" width="161px">
|
||||||
|
</a>
|
||||||
<!-- AOC TILES END -->
|
<!-- AOC TILES END -->
|
||||||
135
day17.py
135
day17.py
@ -1,5 +1,3 @@
|
|||||||
import math
|
|
||||||
import sys
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from tools.aoc import AOCDay
|
from tools.aoc import AOCDay
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@ -28,7 +26,6 @@ class Computer:
|
|||||||
self.instr_pointer = 0
|
self.instr_pointer = 0
|
||||||
self.__code = code
|
self.__code = code
|
||||||
self.code = [(OpCode(code[x]), code[x + 1]) for x in range(0, len(code), 2)]
|
self.code = [(OpCode(code[x]), code[x + 1]) for x in range(0, len(code), 2)]
|
||||||
self.check_output = False
|
|
||||||
self.op = {
|
self.op = {
|
||||||
OpCode.ADV: self.adv,
|
OpCode.ADV: self.adv,
|
||||||
OpCode.BXL: self.bxl,
|
OpCode.BXL: self.bxl,
|
||||||
@ -87,14 +84,8 @@ class Computer:
|
|||||||
|
|
||||||
def out(self, operand: int) -> None:
|
def out(self, operand: int) -> None:
|
||||||
value = self.get_combo_value(operand) % 8
|
value = self.get_combo_value(operand) % 8
|
||||||
if not self.check_output:
|
|
||||||
self.instr_pointer += 1
|
|
||||||
self.output.append(value)
|
self.output.append(value)
|
||||||
elif value != self.__code[len(self.output)]:
|
|
||||||
self.instr_pointer = len(self.code)
|
|
||||||
else:
|
|
||||||
self.instr_pointer += 1
|
self.instr_pointer += 1
|
||||||
self.output.append(value)
|
|
||||||
|
|
||||||
def bdv(self, operand: int) -> None:
|
def bdv(self, operand: int) -> None:
|
||||||
self.reg_b = self.reg_a // (2 ** self.get_combo_value(operand))
|
self.reg_b = self.reg_a // (2 ** self.get_combo_value(operand))
|
||||||
@ -107,25 +98,31 @@ class Computer:
|
|||||||
def get_output(self) -> str:
|
def get_output(self) -> str:
|
||||||
return ",".join(str(x) for x in self.output)
|
return ",".join(str(x) for x in self.output)
|
||||||
|
|
||||||
def run_code(self) -> None:
|
def run(self, init_a: int = None) -> str:
|
||||||
|
self.reset()
|
||||||
|
if init_a is not None:
|
||||||
|
self.reg_a = init_a
|
||||||
|
|
||||||
while self.instr_pointer < len(self.code):
|
while self.instr_pointer < len(self.code):
|
||||||
# print("Exec", self.instr_pointer)
|
|
||||||
op_code, operand = self.code[self.instr_pointer]
|
op_code, operand = self.code[self.instr_pointer]
|
||||||
self.op[op_code](operand)
|
self.op[op_code](operand)
|
||||||
|
|
||||||
|
return self.get_output()
|
||||||
|
|
||||||
|
|
||||||
class Day(AOCDay):
|
class Day(AOCDay):
|
||||||
inputs = [
|
inputs = [
|
||||||
[
|
[
|
||||||
("4,6,3,5,6,3,5,2,1,0", "input17_test"),
|
("4,6,3,5,6,3,5,2,1,0", "input17_test"),
|
||||||
("7,1,2,3,2,6,7,2,5", "input17_neil"),
|
("7,1,2,3,2,6,7,2,5", "input17_neil"),
|
||||||
|
("1,7,6,5,1,0,5,0,7", "input17_dennis"),
|
||||||
("1,6,3,6,5,6,5,1,7", "input17"),
|
("1,6,3,6,5,6,5,1,7", "input17"),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
(117440, "input17_test2"),
|
(117440, "input17_test2"),
|
||||||
(202356708354602, "input17_neil"),
|
(202356708354602, "input17_neil"),
|
||||||
(236555995274861, "input17_dennis"),
|
(236555995274861, "input17_dennis"),
|
||||||
(None, "input17"),
|
(247839653009594, "input17"),
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -135,111 +132,35 @@ class Day(AOCDay):
|
|||||||
|
|
||||||
def part1(self) -> Any:
|
def part1(self) -> Any:
|
||||||
computer = Computer(*self.parse_input())
|
computer = Computer(*self.parse_input())
|
||||||
computer.run_code()
|
return computer.run()
|
||||||
return computer.get_output()
|
|
||||||
|
|
||||||
def part2(self) -> Any:
|
def part2(self) -> Any:
|
||||||
a, b, c, prog = self.parse_input()
|
a, b, c, prog = self.parse_input()
|
||||||
expected_output = ",".join(str(x) for x in prog)
|
expected_output = ",".join(str(x) for x in prog)
|
||||||
computer = Computer(a, b, c, prog)
|
computer = Computer(a, b, c, prog)
|
||||||
computer.check_output = True
|
|
||||||
|
|
||||||
def run_computer(v: int) -> str:
|
def get_match_pos(a: str, b: str) -> int:
|
||||||
computer.reset()
|
m = 0
|
||||||
computer.reg_a = v
|
for x, y in zip(reversed(a), reversed(b)):
|
||||||
computer.run_code()
|
if x == y:
|
||||||
return computer.get_output()
|
m += 1
|
||||||
|
|
||||||
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:
|
|
||||||
init_reg = init_a * (8**factor) + additive
|
|
||||||
output = run_computer(init_reg)
|
|
||||||
|
|
||||||
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:
|
else:
|
||||||
additive = int(bit_match, 8)
|
break
|
||||||
factor = bit_width
|
|
||||||
bit_width += bit_add
|
|
||||||
bit_add -= 1
|
|
||||||
init_a = 0
|
|
||||||
|
|
||||||
print(
|
return m
|
||||||
f"{init_reg=} ({oct(init_reg)}), {factor=}, additive={oct(additive)}, {output=}, {expected_output=}"
|
|
||||||
)
|
|
||||||
best = len(output)
|
|
||||||
|
|
||||||
if init_a % 1_000_000 == 0:
|
num = 0
|
||||||
print(init_a, init_reg)
|
for factor in range(len(prog)):
|
||||||
init_a += 1
|
for i in range(8**len(prog)):
|
||||||
|
output = computer.run(num + i)
|
||||||
print(init_a - 1, (init_a - 1) * (8**factor) + additive)
|
if get_match_pos(output, expected_output) == (2 * factor) + 1:
|
||||||
output = run_computer(init_reg)
|
if factor < len(prog) - 1:
|
||||||
print(output)
|
num = (i + num) * 8
|
||||||
if output == expected_output:
|
|
||||||
return init_reg
|
|
||||||
return ""
|
|
||||||
|
|
||||||
first = []
|
|
||||||
for i, c in enumerate(prog):
|
|
||||||
reg_a_init = 0
|
|
||||||
|
|
||||||
while len(first) <= i:
|
|
||||||
computer.reset()
|
|
||||||
computer.reg_a = reg_a_init
|
|
||||||
computer.run_code()
|
|
||||||
if int(computer.get_output()[0]) == c:
|
|
||||||
first.append(reg_a_init)
|
|
||||||
|
|
||||||
reg_a_init += 1
|
|
||||||
|
|
||||||
print(first)
|
|
||||||
result = 0
|
|
||||||
for i, c in enumerate(reversed(first)):
|
|
||||||
result = result << 3
|
|
||||||
result += c // 8
|
|
||||||
# result = sum(((x * (8 ** i) for i, x in enumerate(first))))
|
|
||||||
print(result)
|
|
||||||
|
|
||||||
computer.reset()
|
|
||||||
computer.reg_a = result
|
|
||||||
computer.run_code()
|
|
||||||
print(computer.get_output())
|
|
||||||
if computer.get_output() == expected_output:
|
|
||||||
return result
|
|
||||||
|
|
||||||
while computer.get_output() != expected_output:
|
|
||||||
result -= 1
|
|
||||||
computer.reset()
|
|
||||||
computer.reg_a = result
|
|
||||||
computer.run_code()
|
|
||||||
|
|
||||||
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)
|
|
||||||
computer.reset()
|
|
||||||
computer.reg_a = result
|
|
||||||
computer.run_code()
|
|
||||||
print(expected_output)
|
|
||||||
print(computer.get_output())
|
|
||||||
|
|
||||||
if computer.get_output() == expected_output:
|
|
||||||
return result
|
|
||||||
else:
|
else:
|
||||||
return ""
|
num += i
|
||||||
|
break
|
||||||
|
|
||||||
|
return num
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
5
inputs/input17_jonathan
Normal file
5
inputs/input17_jonathan
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Register A: 27334280
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 2,4,1,2,7,5,0,3,1,7,4,1,5,5,3,0
|
||||||
Loading…
Reference in New Issue
Block a user