Solution to problem 7 in Python
This commit is contained in:
parent
7c688d4162
commit
b09a78e28c
@ -88,5 +88,78 @@ def part_1() -> None:
|
||||
print(f"The name of the bottom program is {root_program}")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# The programs explain the situation: they can't get down. Rather, they could
|
||||
# get down, if they weren't expending all of their energy trying to keep the
|
||||
# tower balanced. Apparently, one program has the wrong weight, and until it's
|
||||
# fixed, they're stuck here.
|
||||
|
||||
# For any program holding a disc, each program standing on that disc forms a
|
||||
# sub-tower. Each of those sub-towers are supposed to be the same weight, or
|
||||
# the disc itself isn't balanced. The weight of a tower is the sum of the
|
||||
# weights of the programs in that tower.
|
||||
|
||||
# In the example above, this means that for ugml's disc to be balanced, gyxo,
|
||||
# ebii, and jptl must all have the same weight, and they do: 61.
|
||||
|
||||
# However, for tknk to be balanced, each of the programs standing on its disc
|
||||
# and all programs above it must each match. This means that the following sums
|
||||
# must all be the same:
|
||||
|
||||
# ugml + (gyxo + ebii + jptl) = 68 + (61 + 61 + 61) = 251
|
||||
# padx + (pbga + havc + qoyq) = 45 + (66 + 66 + 66) = 243
|
||||
# fwft + (ktlj + cntj + xhth) = 72 + (57 + 57 + 57) = 243
|
||||
|
||||
# As you can see, tknk's disc is unbalanced: ugml's stack is heavier than the
|
||||
# other two. Even though the nodes above ugml are balanced, ugml itself is too
|
||||
# heavy: it needs to be 8 units lighter for its stack to weigh 243 and keep the
|
||||
# towers balanced. If this change were made, its weight would be 60.
|
||||
|
||||
# Given that exactly one program is the wrong weight, what would its weight
|
||||
# need to be to balance the entire tower?
|
||||
|
||||
|
||||
def child_values(node, node_map, node_values):
|
||||
weights, unbalanced = [], []
|
||||
children = node_map[node]
|
||||
for child in children:
|
||||
if child in node_map.keys():
|
||||
child_weight, child_balance = child_values(
|
||||
child, node_map, node_values
|
||||
)
|
||||
value = sum(child_weight) + node_values[child]
|
||||
unbalanced.append(child_balance)
|
||||
else:
|
||||
value = node_values[child]
|
||||
weights.append(value)
|
||||
if len(set(weights)) != 1:
|
||||
unbalanced.append((node_map[node], weights))
|
||||
return weights, unbalanced
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
node_map, node_values = {}, {}
|
||||
for line in towers:
|
||||
if "->" in line:
|
||||
lhs, rhs = line.split(" -> ")
|
||||
parent, value = lhs.split()
|
||||
node_values[parent] = int(value[1:-1])
|
||||
_childs = rhs.split(", ")
|
||||
node_map[parent] = [child for child in _childs]
|
||||
else:
|
||||
child, value = line.split()
|
||||
node_values[child] = int(value[1:-1])
|
||||
|
||||
_, unbalance = child_values("rqwgj", node_map, node_values)
|
||||
|
||||
heavier_child_idx = unbalance[0][0][5][1].index(max(unbalance[0][0][5][1]))
|
||||
heavier_child = unbalance[0][0][5][0][heavier_child_idx]
|
||||
unbalanced_child = node_values[heavier_child]
|
||||
|
||||
print(f"To balance the tower, the weight must be {unbalanced_child - 8}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
||||
|
Loading…
Reference in New Issue
Block a user