Solution to problem 18 in Python

This commit is contained in:
David Doblas Jiménez 2022-01-09 21:17:35 +01:00
parent ae50bcc214
commit 884fcca61f

102
src/2020/P18.py Normal file
View File

@ -0,0 +1,102 @@
# --- Day 18: Operation Order ---
# As you look out the window and notice a heavily-forested continent slowly
# appear over the horizon, you are interrupted by the child sitting next to
# you. They're curious if you could help them with their math homework.
# Unfortunately, it seems like this "math" follows different rules than you
# remember.
# The homework (your puzzle input) consists of a series of expressions that
# consist of addition (+), multiplication (*), and parentheses ((...)). Just
# like normal math, parentheses indicate that the expression inside must be
# evaluated before it can be used by the surrounding expression. Addition still
# finds the sum of the numbers on both sides of the operator, and
# multiplication still finds the product.
# However, the rules of operator precedence have changed. Rather than
# evaluating multiplication before addition, the operators have the same
# precedence, and are evaluated left-to-right regardless of the order in which
# they appear.
# For example, the steps to evaluate the expression 1 + 2 * 3 + 4 * 5 + 6 are
# as follows:
# 1 + 2 * 3 + 4 * 5 + 6
# 3 * 3 + 4 * 5 + 6
# 9 + 4 * 5 + 6
# 13 * 5 + 6
# 65 + 6
# 71
# Parentheses can override this order; for example, here is what happens if
# parentheses are added to form 1 + (2 * 3) + (4 * (5 + 6)):
# 1 + (2 * 3) + (4 * (5 + 6))
# 1 + 6 + (4 * (5 + 6))
# 7 + (4 * (5 + 6))
# 7 + (4 * 11 )
# 7 + 44
# 51
# Here are a few more examples:
# 2 * 3 + (4 * 5) becomes 26.
# 5 + (8 * 3 + 9 + 3 * 4 * 3) becomes 437.
# 5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4)) becomes 12240.
# ((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2 becomes 13632.
# Before you can help with the homework, you need to understand it yourself.
# Evaluate the expression on each line of the homework; what is the sum of the
# resulting values?
with open("files/P18.txt", "r") as f:
homework = [line for line in f.read().strip().split("\n")]
def eval(n1, n2, op) -> int:
if op == "+":
return n1 + n2
elif op == "*":
return n1 * n2
def simplify(expr) -> str:
while len(expr) > 1:
n1 = int(expr.pop())
op = expr.pop()
n2 = int(expr.pop())
result = eval(n1, n2, op)
expr.append(str(result))
return expr[0]
def part_1() -> None:
total = 0
for line in homework:
line = line.replace("(", "( ")
line = line.replace(")", " )")
expr = line.split()
stack = []
for char in expr:
if char.isdigit() or char in ["+", "*", "("]:
stack.append(char)
elif char == ")":
ordered_stack = []
while stack[len(stack) - 1] != "(":
ordered_stack.append(stack.pop())
stack.pop()
result = simplify(ordered_stack)
stack.append(result)
stack.reverse()
result = simplify(stack)
total += int(result)
print(f"The result of evaluating my homework is {total}")
if __name__ == "__main__":
part_1()