Skip to content

Commit

Permalink
Merge pull request #117 from ephemient/py/day17
Browse files Browse the repository at this point in the history
Day 17: Chronospatial Computer
  • Loading branch information
ephemient authored Dec 18, 2024
2 parents c339f6e + 94fc79a commit 4fdba00
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ Development occurs in language-specific directories:
|[Day14.hs](hs/src/Day14.hs)|[Day14.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day14.kt)|[day14.py](py/aoc2024/day14.py)|[day14.rs](rs/src/day14.rs)|
|[Day15.hs](hs/src/Day15.hs)|[Day15.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day15.kt)|[day15.py](py/aoc2024/day15.py)|[day15.rs](rs/src/day15.rs)|
|[Day16.hs](hs/src/Day16.hs)|[Day16.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day16.kt)|[day16.py](py/aoc2024/day16.py)|[day16.rs](rs/src/day16.rs)|
|[Day17.hs](hs/src/Day17.hs)|[Day17.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day17.kt)|||
|[Day17.hs](hs/src/Day17.hs)|[Day17.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day17.kt)|[day17.py](py/aoc2024/day17.py)||
99 changes: 99 additions & 0 deletions py/aoc2024/day17.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""
Day 17: Chronospatial Computer
"""

import re
from typing import Generator

SAMPLE_INPUT_1 = """
Register A: 729
Register B: 0
Register C: 0
Program: 0,1,5,4,3,0
"""
SAMPLE_INPUT_2 = """
Register A: 2024
Register B: 0
Register C: 0
Program: 0,3,5,4,3,0
"""

_pattern = re.compile(r"A: (\d+)|B: (\d+)|C: (\d+)|Program: ([\d,]*)")


def _parse(data: str) -> tuple[int, int, int, list[int]]:
a, b, c, program = 0, 0, 0, []
for match in _pattern.finditer(data):
if capture := match.group(1):
a = int(capture)
elif capture := match.group(2):
b = int(capture)
elif capture := match.group(3):
c = int(capture)
else:
program = [int(num) for num in match.group(4).split(",")]
return a, b, c, program


def _run(a: int, b: int, c: int, program: list[int]) -> Generator[int]:
ip = 0
while 0 <= ip and ip + 1 < len(program):
instruction = program[ip]
operand = program[ip + 1]
combo = (0, 1, 2, 3, a, b, c)[operand] if 0 <= operand < 7 else None
match instruction:
case 0:
a = a >> combo
case 1:
b = b ^ operand
case 2:
b = combo & 7
case 3:
if a:
ip = operand
continue
case 4:
b = b ^ c
case 5:
yield combo & 7
case 6:
b = a >> combo
case 7:
c = a >> combo
case _:
raise NotImplementedError()
ip += 2


def part1(data: str) -> str:
"""
>>> part1(SAMPLE_INPUT_1)
'4,6,3,5,6,3,5,2,1,0'
"""
a, b, c, program = _parse(data)
return ",".join(map(str, _run(a, b, c, program)))


def part2(data: str) -> int:
"""
>>> part2(SAMPLE_INPUT_2)
117440
"""
a, b, c, program = _parse(data)
expected = ",".join(map(str, program))
candidates = [0]
while candidates:
keys = [8 * a + b for a in candidates for b in range(8)]
candidates.clear()
for a in keys:
value = ",".join(map(str, _run(a, b, c, program)))
if value == expected:
return a
if expected.endswith("," + value):
candidates.append(a)
return None


parts = (part1, part2)
1 change: 1 addition & 0 deletions py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ day13 = "aoc2024.day13:parts"
day14 = "aoc2024.day14:parts"
day15 = "aoc2024.day15:parts"
day16 = "aoc2024.day16:parts"
day17 = "aoc2024.day17:parts"

[build-system]
requires = ["poetry-core"]
Expand Down

0 comments on commit 4fdba00

Please sign in to comment.