from typing import Dict import re lines = (x.strip() for x in open("input.txt")) class Node: contains: Dict[str, int] = None visited: bool = None contained_by: Dict[str, int] = None count: int = None def __init__(self): self.contains = {} self.visited = False self.count = 0 self.contained_by = {} class BaseGraph: _nodes: Dict[str, Node] = None _regex_base = re.compile(r"^([a-z ]+?) bags? contains? (.+?)\.$") _regex_contain = re.compile(r"^(\d)+ ([a-z ]+?) bags?$") def __init__(self): self._nodes = {} def add(self, name: str, contains: Dict[str, int]): if name not in self._nodes: self._nodes[name] = Node() self._nodes[name].contains = contains for key, val in contains.items(): if key not in self._nodes: self._nodes[key] = Node() self._nodes[key].contained_by[name] = val def add_line(self, line: str): base = self._regex_base.match(line) name = base.group(1) info_str = base.group(2) if info_str == "no other bags": contains = {} else: info_str = map(lambda x: self._regex_contain.match(x).groups(), info_str.split(", ")) contains = dict(((x[1], int(x[0])) for x in info_str)) self.add(name, contains)