47 lines
1.3 KiB
Python
47 lines
1.3 KiB
Python
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)
|