Advent of Code 2024 - Day 3: Mull It Over
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from advent import parse, re input = "".join(parse(3)) def solve(ignore_commands=False): enabled = True sum = 0 for match in re.finditer(r"mul\((\d{1,3}),(\d{1,3})\)|don't\(\)|do\(\)", input): if match.group() == "do()": enabled = True elif match.group() == "don't()": enabled = False elif enabled or ignore_commands: sum += (int(match.group(1)) * int(match.group(2))) return sum # --------------------------------------------------------------------------------------------- assert solve(True) == 174960292 assert solve() == 56275602 |
Parsing
Today’s input comes in multiple lines, but for our purposes, we just want one long string. parse()
will give us a tuple of strings, and we join them together with join()
using an empty string as the separator:
1 |
input = "".join(parse(3)) |
Solution
Parts 1 and 2 are similar enough today that we’ll solve them both with a single function that differentiates between the parts with a parameter indicating whether we should ignore the do()
and don't()
commands.
The key element today is a regular expression. There are three expressions we care about: mul(m,n)
, do()
and don't()
, so we’ll create patterns to match those three alternatives, and combine them with a vertical bar |
:
To match mul(m,n)
, where m and n are 1 to 3 numeric digits: mul\((\d{1,3}),(\d{1,3})\)
We use subgroups so we can easily extract m
and n
later.
To match do()
: do\(\)
To match don't()
: don't\(\)
Once we have the proper regular expression matching in place, we simply loop over all the matches, and perform the appropriate action:
do()
—> setenabled
toTrue
don't()
—> setenabled
toFalse
mul(m,n)
—> if eitherenabled
orignore_commands
isTrue
add the product ofm
andn
tosum
New Python Concepts
int()
join()
Match.group()
re.finditer()
re
- Default parameters
def solve(ignore_commands=False)
Conclusion
While custom parsing code may perform better on today’s task, the convenience of regular expressions make them a win in my opinion. Python has fantastic support for regular expressions.