Solution to problem 18 in Python
This commit is contained in:
102
src/2020/P18.py
Normal file
102
src/2020/P18.py
Normal 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()
|
||||||
Reference in New Issue
Block a user