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()—> setenabledtoTruedon't()—> setenabledtoFalsemul(m,n)—> if eitherenabledorignore_commandsisTrueadd the product ofmandntosum
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.