-
Notifications
You must be signed in to change notification settings - Fork 0
/
18.py
110 lines (91 loc) · 2.8 KB
/
18.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
from collections import deque
from pathlib import Path
import operator
import math
import functools
def read():
path = Path(__file__).parent / "input18.txt"
rows = []
with open(path) as f:
for line in f.readlines():
row = list(line.strip().replace(" ", ""))
rows.append(row)
return rows
def p1(rows):
operators = {
"+": operator.add,
"*": operator.mul,
}
total = 0
for row in rows:
stack = []
queue = deque(row)
while queue:
current = queue.popleft()
if current == "(":
stack.append("(")
elif current == ")":
value = stack.pop()
# pop the previously stored left bracket
stack.pop()
if stack and stack[-1] != "(":
func = stack.pop()
stack.append(func(value))
else:
stack.append(value)
elif current in ("+", "*"):
value = stack.pop()
stack.append(functools.partial(operators[current], value))
else:
if stack and not stack[-1] == "(":
func = stack.pop()
stack.append(func(int(current)))
else:
stack.append(int(current))
total += stack.pop()
return total
def p2(rows):
def helper(queue):
stack = []
is_addition = False
is_mulitiplication = False
while queue:
current = queue.popleft()
if current == "(":
result = helper(queue)
if is_mulitiplication:
is_mulitiplication = False
stack.append(result)
elif is_addition:
is_addition = False
operand = stack.pop()
stack.append(operand + result)
else:
stack.append(result)
elif current == "+":
is_addition = True
elif current == "*":
is_mulitiplication = True
elif current == ")":
# multiply everything and return
return math.prod(stack)
elif is_mulitiplication:
is_mulitiplication = False
stack.append(int(current))
elif is_addition:
is_addition = False
operand = stack.pop()
stack.append(operand + int(current))
else:
stack.append(int(current))
return math.prod(stack)
total = 0
for row in rows:
total += helper(deque(row))
return total
def main():
input = read()
print(p1(input))
print(p2(input))
if __name__ == "__main__":
main()