Urgh this was horrible. I should have taken the opportunity to learn some kind of graph library to do this, but I've spent way enough time looking at it now.
fromcollectionsimportdefaultdictclassRuleParser():def__init__(self):self.containment_tree=defaultdict(lambda:defaultdict(list))defparse_row(self,row):ifrow.strip()=="":returnrow=row.replace(' bags','').replace(' bag','').replace('.','').strip()outer,contents=row.split(' contain ')content_rules=contents.split(', ')forcontained_ruleincontent_rules:words=contained_rule.split(' ')n=0ifwords[0]=="no"elseint(words[0])colour=" ".join(words[1:])colour=colourifn>0else"no other"self.containment_tree[outer][colour]=ndeffind_in_subtree(self,target_color):outers=set()defsearch_subtree(for_colour):forouterinself.containment_tree:iffor_colourinself.containment_tree[outer]:outers.add(outer)search_subtree(outer)search_subtree(target_color)returnlen(outers)def_n_in_subtree(self,outer_bag):total_children=1forinner_baginparser.containment_tree[outer_bag]:n_this_colour=parser.containment_tree[outer_bag][inner_bag]n_children=self._n_in_subtree(inner_bag)total_children+=n_this_colour*n_childrenreturntotal_childrendefn_in_children(self,outer_bag):returnself._n_in_subtree(outer_bag)-1parser=RuleParser()withopen("input.txt","r")asinput:forrowininput:parser.parse_row(row)goal_colour='shiny gold'part_1=parser.find_in_subtree(goal_colour)print(f"Part 1 solution: {part_1} colours can ultimately contain a {goal_colour} bag")part_2=parser.n_in_children(goal_colour)print(f"Part 2 solution: a {goal_colour} bag has to contain {part_2} other bags")
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Urgh this was horrible. I should have taken the opportunity to learn some kind of graph library to do this, but I've spent way enough time looking at it now.