parents = new_parents new_parents = set() for parent in parents: new_parents.update(parent_dict.get(parent, set())) new_parents -= all_parents all_parents.update(new_parents) return all_parents def count_bags(parsed_rules: Dict[str, List[Tuple[str, int]]], bag_type: str) -> int: return 1 + sum([ num * count_bags(parsed_rules, sub_type) for sub_type, num in parsed_rules[bag_type] ]) def part_1(rules: List[str], bag_type: str) -> int: parent_dict = get_parent_dict(parse_rules(rules)) return len(find_all_parents(parent_dict, bag_type)) def part_2(rules: List[str], bag_type: str) -> int: parsed_rules = parse_rules(rules) return count_bags(parsed_rules, bag_type) - 1 if __name__ == "__main__": print(part_2(get_input(), "shiny gold"))
def is_valid(passport: Set[str]) -> bool: if REQUIRED_FIELDS.keys() - passport: return False if passport - REQUIRED_FIELDS.keys() - OPTIONAL_FIELDS: return False return True def is_valid_2(passport: Dict[str, str]) -> bool: if not is_valid(set(passport.keys())): return False return all([ REQUIRED_FIELDS[key](value) if key in REQUIRED_FIELDS else True for key, value in passport.items() ]) def part_1(data: List[str]) -> int: passports = organize_passports(data) return sum(map(is_valid, passports)) def part_2(data: List[str]) -> int: passports = organize_passports(data) return sum(map(is_valid_2, passports)) if __name__ == "__main__": print(part_2(get_input()))