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)