···11-import sys
21import re
32import fileinput
43···3938print 'Name of bottom program:', root.name
403941404141+BAD_WEIGHTS = {}
4242+4343+4244def program_weight(node):
4345 if not node.aboves:
4446 return node.weight
45474648 weights = [program_weight(a) for a in node.aboves]
47494848- # Since we're performing DFS, we are guaranteed to encounter the problem
4949- # disc here first; therefore, we compute the correct answer and exit.
5050+ # Keep track of discs whose children have different weights
5051 if len(set(weights)) != 1:
5151- for i, w in enumerate(weights):
5252- if weights.count(w) == 1:
5353- diff = w
5454- wrong_disc = node.aboves[i].name
5555- else:
5656- same = w
5757-5858- proper_weight = DISCS[wrong_disc].weight + (same - diff)
5959- print "Proper weight of `{}`: {}".format(wrong_disc, proper_weight)
6060- sys.exit()
5252+ BAD_WEIGHTS[node.name] = weights
61536254 return sum(weights) + node.weight
635564566565-# Initialize the recursion, which will also find the solution.
5757+# Seed `BAD_WEIGHTS`
6658program_weight(root)
5959+6060+# Traverse from root until the offending disc is found
6161+bad_disc = root
6262+while True:
6363+ for a in bad_disc.aboves:
6464+ if a.name in BAD_WEIGHTS:
6565+ bad_disc = a
6666+ break
6767+ else:
6868+ break
6969+7070+# Determine the correct weight of the child disc
7171+weights = BAD_WEIGHTS[bad_disc.name]
7272+7373+for i, w in enumerate(weights):
7474+ if weights.count(w) == 1:
7575+ diff = w
7676+ wrong_disc = bad_disc.aboves[i].name
7777+ else:
7878+ same = w
7979+8080+proper_weight = DISCS[wrong_disc].weight + (same - diff)
8181+print "Proper weight of `{}`: {}".format(wrong_disc, proper_weight)