Advent of Code 2024 day 3
My solution for day 3. The re
module is one of my favourites in Python’s standard library.
import math
import re
import unittest
def part_one(raw_input):
matches = re.findall(r"mul\((\d{1,3}),(\d{1,3})\)", raw_input)
return sum([math.prod([int(value) for value in match]) for match in matches])
def do_or_dont(conditional_matches, location):
enabled = True
mapped_matches = {match.start(): match[1] for match in conditional_matches}
for i in range(location):
if i in mapped_matches:
enabled = mapped_matches[i] == "do"
return enabled
def part_two(raw_input):
mul_matches = re.finditer(r"mul\((\d{1,3}),(\d{1,3})\)", raw_input)
conditional_matches = list(re.finditer(r"(do|don't)\(\)", raw_input))
return sum(
[
math.prod([int(value) for value in match.groups()])
for match in mul_matches
if do_or_dont(conditional_matches, match.start())
]
)
class TestExamples(unittest.TestCase):
def test_part_one(self):
self.assertEqual(
part_one(
"xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"
),
161,
)
def test_part_two(self):
self.assertEqual(
part_two(
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
),
48,
)
if __name__ == "__main__":
with open("day_03_input.txt") as file:
raw_input = file.read().strip()
print(f"{part_one(raw_input)=}")
print(f"{part_two(raw_input)=}")