Solution to Day 3
This commit is contained in:
101
src/Year_2024/Day_03.py
Normal file
101
src/Year_2024/Day_03.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
# --- Day 3: Mull It Over ---
|
||||||
|
|
||||||
|
# "Our computers are having issues, so I have no idea if we have any Chief
|
||||||
|
# Historians in stock! You're welcome to check the warehouse, though," says the
|
||||||
|
# mildly flustered shopkeeper at the North Pole Toboggan Rental Shop. The
|
||||||
|
# Historians head out to take a look.
|
||||||
|
|
||||||
|
# The shopkeeper turns to you. "Any chance you can see why our computers are
|
||||||
|
# having issues again?"
|
||||||
|
|
||||||
|
# The computer appears to be trying to run a program, but its memory (your
|
||||||
|
# puzzle input) is corrupted. All of the instructions have been jumbled up!
|
||||||
|
|
||||||
|
# It seems like the goal of the program is just to multiply some numbers. It
|
||||||
|
# does that with instructions like mul(X,Y), where X and Y are each 1-3 digit
|
||||||
|
# numbers. For instance, mul(44,46) multiplies 44 by 46 to get a result of 2024.
|
||||||
|
# Similarly, mul(123,4) would multiply 123 by 4.
|
||||||
|
|
||||||
|
# However, because the program's memory has been corrupted, there are also many
|
||||||
|
# invalid characters that should be ignored, even if they look like part of a
|
||||||
|
# mul instruction. Sequences like mul(4*, mul(6,9!, ?(12,34), or mul ( 2 , 4 )
|
||||||
|
# do nothing.
|
||||||
|
|
||||||
|
# For example, consider the following section of corrupted memory:
|
||||||
|
|
||||||
|
# xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
|
||||||
|
|
||||||
|
# Only the four highlighted sections are real mul instructions. Adding up the
|
||||||
|
# result of each instruction produces 161 (2*4 + 5*5 + 11*8 + 8*5).
|
||||||
|
|
||||||
|
# Scan the corrupted memory for uncorrupted mul instructions. What do you get if
|
||||||
|
# you add up all of the results of the multiplications?
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
with open("P3.txt") as f:
|
||||||
|
memory = [line for line in f.read().strip().split()]
|
||||||
|
|
||||||
|
def part_1():
|
||||||
|
total = 0
|
||||||
|
pattern = re.compile(r"mul\((\d{1,3}),(\d{1,3})\)")
|
||||||
|
for line in memory:
|
||||||
|
matches = pattern.findall(line)
|
||||||
|
for match in matches:
|
||||||
|
a, b = map(int, match)
|
||||||
|
total += a * b
|
||||||
|
print(f"The sum of all multiplication results is {total}")
|
||||||
|
|
||||||
|
|
||||||
|
# --- Part Two ---
|
||||||
|
|
||||||
|
# As you scan through the corrupted memory, you notice that some of the
|
||||||
|
# conditional statements are also still intact. If you handle some of the
|
||||||
|
# uncorrupted conditional statements in the program, you might be able to get
|
||||||
|
# an even more accurate result.
|
||||||
|
|
||||||
|
# There are two new instructions you'll need to handle:
|
||||||
|
|
||||||
|
# The do() instruction enables future mul instructions.
|
||||||
|
# The don't() instruction disables future mul instructions.
|
||||||
|
|
||||||
|
# Only the most recent do() or don't() instruction applies. At the beginning of
|
||||||
|
# the program, mul instructions are enabled.
|
||||||
|
|
||||||
|
# For example:
|
||||||
|
|
||||||
|
# xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
|
||||||
|
|
||||||
|
# This corrupted memory is similar to the example from before, but this time
|
||||||
|
# the mul(5,5) and mul(11,8) instructions are disabled because there is a
|
||||||
|
# don't() instruction before them. The other mul instructions function normally,
|
||||||
|
# including the one at the end that gets re-enabled by a do() instruction.
|
||||||
|
|
||||||
|
# This time, the sum of the results is 48 (2*4 + 8*5).
|
||||||
|
|
||||||
|
# Handle the new instructions; what do you get if you add up all of the results
|
||||||
|
# of just the enabled multiplications?
|
||||||
|
|
||||||
|
def part_2():
|
||||||
|
total = 0
|
||||||
|
pattern = re.compile(r"mul\((\d{1,3}),(\d{1,3})\)|(do\(\))|((don't\(\)))")
|
||||||
|
enabled = True
|
||||||
|
for line in memory:
|
||||||
|
tokens = re.split(r"(do\(\)|don't\(\)|mul\(\d{1,3},\d{1,3}\))", line)
|
||||||
|
for token in tokens:
|
||||||
|
if token == "do()":
|
||||||
|
enabled = True
|
||||||
|
elif token == "don't()":
|
||||||
|
enabled = False
|
||||||
|
else:
|
||||||
|
matches = pattern.findall(token)
|
||||||
|
for match in matches:
|
||||||
|
if enabled:
|
||||||
|
a, b = map(int, match[:2])
|
||||||
|
total += a * b
|
||||||
|
print(f"The sum of all enabled multiplication results is {total}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
||||||
|
part_2()
|
||||||
Reference in New Issue
Block a user