/
aoc_18a.py
84 lines (77 loc) · 2.85 KB
/
aoc_18a.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
fin = open("input_18.txt")
def magnitude(sfnumber):
v = 0
for i, f in ((0, 3), (1, 2)):
if type(sfnumber[i]) is int:
v += f * int(sfnumber[i])
else:
v += f * magnitude(sfnumber[i])
return v
def nreduce(nstring):
nstring = nstring.replace(" ", "")
has_changed = True
while has_changed:
has_changed = False
ldn_pos = 0 # left neighbor digit
rdn_pos = -1 # right neighbor digit
depth = 0
for i, char in enumerate(nstring):
if char.isdigit():
ldn_pos = i
if char == "]":
depth -= 1
if char == "[":
depth += 1
if depth == 5: # explode
lb_pos = i # left bracket
co_pos = nstring.index(",", i) # comma
rb_pos = nstring.index("]", i) # right bracket
ex_left = nstring[lb_pos + 1 : co_pos] # what flies left
ex_right = nstring[co_pos + 1 : rb_pos] # what flies right
for j in range(rb_pos, len(nstring)):
if nstring[j].isdigit():
rdn_pos = j
break
linsert = "+" + ex_left if ldn_pos > 0 else ""
rinsert = ex_right + "+" if rdn_pos > 0 else ""
nstring = (
nstring[: ldn_pos + 1]
+ linsert
+ nstring[ldn_pos + 1 : lb_pos]
+ "0"
+ nstring[rb_pos + 1 : rdn_pos]
+ rinsert
+ nstring[rdn_pos:]
)
nstring = str(eval(nstring)).replace(" ", "")
has_changed = True
break
if has_changed:
continue
ldn_pos_right = 0
for i, char in enumerate(nstring):
if char.isdigit():
ldn_pos = i
for j in range(i + 1, len(nstring)):
if not nstring[j].isdigit():
ldn_pos_right = j - 1
break
if ldn_pos_right > ldn_pos: # split
to_split = int(nstring[ldn_pos : ldn_pos_right + 1])
nstring = (
nstring[:ldn_pos]
+ "["
+ str(to_split // 2)
+ ","
+ str((to_split + 1) // 2)
+ "]"
+ nstring[ldn_pos_right + 1 :]
)
has_changed = True
break
return nstring
left = fin.readline().strip()
for line in fin:
left = nreduce("[" + left + "," + line.strip() + "]")
print(left)
print(magnitude(eval(left)))