-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathday18.py
102 lines (80 loc) · 2.66 KB
/
day18.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
def perform_operation(stack: list, num: int) -> list[str]:
while stack:
if stack[-1] == '(':
break
operator, left_operand = stack[-1], stack[-2]
stack = stack[:-2]
if operator == '+':
num = left_operand + num
elif operator == '*':
num = left_operand * num
stack.append(num)
return stack
def perform_advance_operation(stack: list, num: int, close_bracket: bool) -> list[str]:
# Perform "*" operations
if close_bracket:
ix = -1
# Find the last position of open bracket - "("
for sx, s in enumerate(stack):
if s == '(':
ix = sx
if ix != -1:
target_stack = stack[ix+1:]
stack = stack[:ix]
else:
target_stack = stack
stack = []
for s in target_stack:
if s != '*': # only "*" and digits are in the target stack
num *= int(s)
# Perform "+" operations
while stack:
if stack[-1] in '(*':
break
operator, left_operand = stack[-1], stack[-2]
stack = stack[:-2]
if operator == '+':
num = left_operand + num
stack.append(num)
return stack
def calculate(expression: str, advance: bool) -> int:
stack = []
ix = 0
while ix < len(expression):
if expression[ix] in '1234567890':
num = int(expression[ix])
if advance:
stack = perform_advance_operation(stack, num, close_bracket=False)
else:
stack = perform_operation(stack, num)
elif expression[ix] in '*+(':
stack.append(expression[ix])
elif expression[ix] in ')':
num = int(stack[-1])
if advance:
stack = stack[:-1]
stack = perform_advance_operation(stack, num, close_bracket=True)
else:
stack = stack[:-2] # stack[-2] must be "("
stack = perform_operation(stack, num)
ix += 1
if advance and (len(stack) > 1):
stack = perform_advance_operation(stack[:-1], int(stack[-1]), close_bracket=True)
return int(stack[0]) # should only be 1 value left at the end
def part1(expressions):
ans = 0
for expression in expressions:
ans += calculate(expression, advance=False)
return ans
def part2(expressions):
ans = 0
for expression in expressions:
ans += calculate(expression, advance=True)
return ans
with open('day18-data.txt') as f:
inputs = [
expression
for expression in f.read().splitlines()
]
print(part1(inputs))
print(part2(inputs))