61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import aoc
|
||
|
|
||
|
|
||
|
def parse_line(line: str):
|
||
|
childs = list()
|
||
|
if ' -> ' in line:
|
||
|
split1 = line.split(' -> ')
|
||
|
childs = list(map(lambda x: x.strip(), split1[1].strip().split(',')))
|
||
|
line = split1[0]
|
||
|
|
||
|
line = line.strip()
|
||
|
line = line.replace('(', '').replace(')', '')
|
||
|
split2 = line.split(' ')
|
||
|
name = split2[0].strip()
|
||
|
weight = int(split2[1].strip())
|
||
|
return name, weight, childs
|
||
|
|
||
|
|
||
|
def calc_weight_rec(fdatamap, key):
|
||
|
w = fdatamap[key][1]
|
||
|
for child in fdatamap[key][2]:
|
||
|
w += calc_weight_rec(fdatamap, child)
|
||
|
return w
|
||
|
|
||
|
|
||
|
def is_balanced(fdatamap, key):
|
||
|
if len(fdatamap[key][2]) == 0:
|
||
|
return True
|
||
|
subweights = list(map(lambda x: calc_weight_rec(fdatamap, x), fdatamap[key][2]))
|
||
|
return len(set(subweights)) == 1
|
||
|
|
||
|
|
||
|
rawinput = aoc.read_input(7)
|
||
|
|
||
|
data = list(map(lambda x: parse_line(x), rawinput.splitlines()))
|
||
|
datamap = {x[0]: x for x in data}
|
||
|
|
||
|
rnodes = list(map(lambda x: x[0], data))
|
||
|
|
||
|
for datum in data:
|
||
|
if is_balanced(datamap, datum[0]):
|
||
|
continue
|
||
|
weights = list(map(lambda x: calc_weight_rec(datamap, x), datum[2]))
|
||
|
if len(set(weights)) != 1:
|
||
|
for idx, w in enumerate(weights):
|
||
|
if weights.count(w) != 1:
|
||
|
continue
|
||
|
if not is_balanced(datamap, datum[2][idx]):
|
||
|
continue
|
||
|
real_direct_subweight = datamap[datum[2][idx]][1]
|
||
|
real_full_subweight = w
|
||
|
wanted_full_subweight = weights[(idx+1) % len(weights)]
|
||
|
wanted_direct_subweight = real_direct_subweight + (wanted_full_subweight - real_full_subweight)
|
||
|
|
||
|
# print(datamap[datum[2][idx]])
|
||
|
# print(real_full_subweight, real_direct_subweight, wanted_full_subweight, wanted_direct_subweight)
|
||
|
# print(datum, weights)
|
||
|
print(wanted_direct_subweight)
|