-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday18.py
108 lines (92 loc) · 2.98 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
103
104
105
106
107
from utils import get_input
def part1(data):
sfsum = data[0]
for sfnum in data[1:]:
sfsum = add(sfsum, sfnum)
sfsum = reduce(sfsum)
return magnitude(eval(sfsum))
def part2(data):
m = 0
for num1 in data:
for num2 in data:
m = max(part1([num1,num2]),m)
return m
def add(exp_a, exp_b):
return '[' + exp_a + ',' + exp_b + ']'
def reduce(expression):
explodes, splits = True, True
while explodes or splits:
explodes, splits = False, False
depth = 0
for i in range(len(expression)):
if expression[i] == ']':
depth -= 1
elif expression[i] == '[':
depth += 1
if expression[i+2] == ']':
print("error")
return None
if depth == 5:
explodes = True
break
if explodes:
expression = explode(expression, i)
continue
for i in range(len(expression)):
if expression[i].isnumeric():
k = 1
while expression[i:i+k+1].isnumeric():
k += 1
if k > 1: # 2 digits => num>=10
expression = split(expression, i, k)
splits = True
break
return expression
def explode(expression, idx):
k_a = 1
while expression[idx+1:idx+k_a+1].isnumeric():
k_a += 1
a = int(expression[idx+1:idx+k_a])
idx_b = idx+k_a+1
k_b = 1
while expression[idx_b:idx_b+k_b+1].isnumeric():
k_b += 1
b = int(expression[idx_b:idx_b+k_b])
new_expression = expression[:idx]+'0'+expression[idx_b+k_b+1:]
#print("explode",expression,"at",expression[idx:idx_b+k_b+1])
i = idx - 1
while i > 0:
i -= 1
if new_expression[i].isnumeric():
k = 0
while new_expression[i-k-1:i+1].isnumeric():
k += 1
c = int(new_expression[i-k:i+1])+a
new_expression = new_expression[:i-k]+str(c)+new_expression[i+max(k,1):]
break
j = idx + 1
while j < len(new_expression)-1:
j += 1
if new_expression[j].isnumeric():
k = 1
while new_expression[j:j+k+1].isnumeric():
k += 1
d = int(new_expression[j:j+k])+b
new_expression = new_expression[:j]+str(d)+new_expression[j+k:]
break
#print(new_expression)
return new_expression
def split(expression, idx, k):
num_to_split = int(expression[idx:idx+k])
a = num_to_split // 2
b = num_to_split // 2 + num_to_split % 2
return expression[:idx] + "[" + str(a) + "," + str(b) + "]" + expression[idx+k:]
def magnitude(expression):
if isinstance(expression, int):
return expression
return 3*magnitude(expression[0])+2*magnitude(expression[1])
if __name__ == "__main__":
day = 18
data = get_input(day)
print(part1(data))
print(part2(data))