53 lines
1.4 KiB
Python
53 lines
1.4 KiB
Python
|
import re
|
||
|
|
||
|
# EXAMPLE = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"
|
||
|
EXAMPLE = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
|
||
|
|
||
|
INST_RE = re.compile(r"(mul\(\d+,\d+\)|do\(\)|don't\(\))")
|
||
|
|
||
|
|
||
|
class ParseInstructions:
|
||
|
"""Parse instructions and get results"""
|
||
|
|
||
|
def __init__(self, input: str):
|
||
|
self.input = input
|
||
|
self.instructions = INST_RE.findall(self.input)
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Part 1 = {self._part1}, Part 2 = {self._part2}"
|
||
|
|
||
|
def _mul(self, inst: str) -> int:
|
||
|
vars = re.findall(r"\d+", inst)
|
||
|
return int(vars[0]) * int(vars[1])
|
||
|
|
||
|
@property
|
||
|
def _part1(self):
|
||
|
outp = 0
|
||
|
for inst in self.instructions:
|
||
|
if inst.startswith("mul"):
|
||
|
outp += self._mul(inst)
|
||
|
return outp
|
||
|
|
||
|
@property
|
||
|
def _part2(self):
|
||
|
outp = 0
|
||
|
enabled = True
|
||
|
for inst in self.instructions:
|
||
|
if inst.startswith("don't"):
|
||
|
enabled = False
|
||
|
elif inst.startswith("do"):
|
||
|
enabled = True
|
||
|
elif inst.startswith("mul") and enabled:
|
||
|
outp += self._mul(inst)
|
||
|
return outp
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
example = ParseInstructions(EXAMPLE)
|
||
|
print(example)
|
||
|
assert example._part1 == 161
|
||
|
assert example._part2 == 48
|
||
|
with open("input.txt", "r") as f:
|
||
|
puzzle = ParseInstructions(f.read())
|
||
|
print(puzzle)
|