116 lines
2.9 KiB
Python
116 lines
2.9 KiB
Python
from lib import get_data
|
|
from math import ceil, floor
|
|
from itertools import combinations
|
|
|
|
data = """[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
|
|
[[[5,[2,8]],4],[5,[[9,9],0]]]
|
|
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
|
|
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
|
|
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
|
|
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
|
|
[[[[5,4],[7,7]],8],[[8,3],8]]
|
|
[[9,3],[[9,9],[6,[4,9]]]]
|
|
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
|
|
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]"""
|
|
data = get_data(__file__)
|
|
|
|
|
|
def parse(line):
|
|
xs = list(line)
|
|
for i in range(len(xs)):
|
|
try:
|
|
xs[i] = int(xs[i])
|
|
except ValueError:
|
|
pass
|
|
assert line == "".join(map(str, xs))
|
|
return xs
|
|
|
|
|
|
def reduce(xs):
|
|
reduced, nesting = False, 0
|
|
for i in range(len(xs)):
|
|
c = xs[i]
|
|
if c == "[" and nesting == 4 and not reduced:
|
|
lhs, rhs = xs[i + 1], xs[i + 3]
|
|
if not (type(lhs) is int and type(rhs) is int):
|
|
continue
|
|
xs = xs[:i] + [0] + xs[i + 5 :]
|
|
|
|
for j in range(i - 1, -1, -1):
|
|
if type(xs[j]) is int:
|
|
xs[j] += lhs
|
|
break
|
|
|
|
for j in range(i + 1, len(xs)):
|
|
if type(xs[j]) is int:
|
|
xs[j] += rhs
|
|
break
|
|
reduced = True
|
|
break
|
|
elif c == "[":
|
|
nesting += 1
|
|
elif c == "]":
|
|
nesting -= 1
|
|
|
|
if not reduced:
|
|
for i in range(len(xs)):
|
|
c = xs[i]
|
|
if type(c) is int and c >= 10:
|
|
p = [floor(c / 2), ceil(c / 2)]
|
|
xs = xs[:i] + ["[", p[0], ",", p[1], "]"] + xs[i + 1 :]
|
|
reduced = True
|
|
break
|
|
return xs
|
|
|
|
|
|
def restore(xs):
|
|
return "".join(map(str, xs))
|
|
|
|
|
|
assert restore(reduce(parse("[[[[[9,8],1],2],3],4]"))) == "[[[[0,9],2],3],4]"
|
|
assert restore(reduce(parse("[7,[6,[5,[4,[3,2]]]]]"))) == "[7,[6,[5,[7,0]]]]"
|
|
assert (
|
|
restore(reduce(parse("[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]")))
|
|
== "[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]"
|
|
)
|
|
assert (
|
|
restore(reduce(parse("[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]")))
|
|
== "[[3,[2,[8,0]]],[9,[5,[7,0]]]]"
|
|
)
|
|
|
|
|
|
def add(a, b):
|
|
s = ["["] + a + [","] + b + ["]"]
|
|
while True:
|
|
ns = reduce(s)
|
|
if s == ns:
|
|
break
|
|
s = ns
|
|
return s
|
|
|
|
|
|
a = "[[[[4,3],4],4],[7,[[8,4],9]]]"
|
|
b = "[1,1]"
|
|
assert restore(add(parse(a), parse(b))) == "[[[[0,7],4],[[7,8],[6,0]]],[8,1]]"
|
|
|
|
lines = list(data.splitlines())
|
|
s = parse(lines[0].strip())
|
|
for line in lines[1:]:
|
|
s = add(s, parse(line.strip()))
|
|
|
|
|
|
def get_mag(xs):
|
|
if type(xs) is int:
|
|
return xs
|
|
return get_mag(xs[0]) * 3 + get_mag(xs[1]) * 2
|
|
|
|
|
|
print(get_mag(eval(restore(s))))
|
|
|
|
lines = list(data.splitlines())
|
|
m = 0
|
|
for a, b in combinations(lines, 2):
|
|
m = max(m, get_mag(eval(restore(add(parse(a), parse(b))))))
|
|
m = max(m, get_mag(eval(restore(add(parse(b), parse(a))))))
|
|
print(m)
|