#!/usr/bin/python3 from pprint import pprint import re rules = {} with open("input") as fh: for ln in fh: m = re.fullmatch(r"(.*) bags contain (.*)\.\n", ln) container = m.group(1) contents = {} for c in m.group(2).split(", "): if m := re.match(r"(\d+) (.*) bag", c): contents[m.group(2)] = int(m.group(1)) assert container not in rules # Assume only one rule for each container rules[container] = contents containers = { "shiny gold" } while True: new_containers = set() for c in containers: for r in rules.items(): if c in r[1]: new_containers.add(r[0]) combined_containers = containers | new_containers pprint(combined_containers) if combined_containers == containers: # nothing added, so we are finished break containers = combined_containers print(len(combined_containers - { "shiny gold" }))