#!/usr/bin/env python3 if __name__ == '__main__': with open('input','r',encoding='utf-8') as file: all_programs = file.readlines() i = 0 for program in all_programs: program = program.split() program[1] = int(program[1].strip('()')) if len(program) > 2: program[2] = [] for j in range(3, len(program)): program[2].append(program[j].strip(',')) program = [program[0], program[1], program[2]] else: program.append([]) all_programs[i] = program i += 1 # at this point, each line is one program in the stack, # and each line is a list of info. # list[0] is the program name. # list[1] is the program weight. # list[2] is a list of other programs which sit directly on top. # for part 1, we simply need to find the program name # which exists in no other list of children! # the datatype of all_programs is # [[string,int,[string, string,...]],[string,int,[string,string,...],...] def find_position(programs_list): all_children = [''] for program in programs_list: if program[2] == []: program = program.append("top") else: children = program[2] if all_children == ['']: all_children = children else: all_children = all_children + children # note: all_children will not have duplicates! # why? can't stand on two programs' heads at once.... for program in programs_list: try: all_children.index(program[0]) except ValueError: program = program.append("bot") for program in programs_list: if len(program) == 3: program = program.append("mid") def rename_programs(programs_list): name_index = [] for program in programs_list: name_index = name_index + [program[0]] i = 0 for program in programs_list: children = program[2] if children != []: j = 0 for child in children: child_index = name_index.index(child) programs_list[i][2][j] = child_index j += 1 # rename program itself programs_list[i][0] = name_index.index(program[0]) i += 1 find_position(all_programs) i = 0 for program in all_programs: if program[3] == "bot": bot_index = i i += 1 bot_name = all_programs[bot_index][0] rename_programs(all_programs) # at this point, all_programs looks like: # [ [0, 123, [4, 8, 14], 'mid'], # [1, 51, [] , 'top'], # [2, 293, [9, 1] , 'mid'], # ... # ] # starting from bot_index, build out the tree. # recursive functions might be helpful! # bot and mid programs have child programs. # all child programs must be balanced such that # the weight of all children (and grandchildren, etc) # must be the same. # starting at bottom, make sure children are balanced. # if children have children, check that those are balanced, # then sum the total weight of child and all ITS children, # making sure that each child is equal. # this explanation is silly. # you get it. def get_weight(programs_list, index): program = programs_list[index] weight = program[1] if( program[3] == "bot") or (program[3] == "mid"): children = program[2] children_weight = 0 for child in children: child_weight = get_weight(programs_list, child) children_weight += child_weight weight += children_weight return weight print(get_weight(all_programs, bot_index)) i = 0 for i in range(10): print(all_programs[i])