48 lines
1.3 KiB
Python
48 lines
1.3 KiB
Python
import re
|
|
|
|
CHILD_PARSE = re.compile(r"(\d+) (.*)")
|
|
PARSED_DICT: dict[str, list[(int, str)]] = {}
|
|
|
|
with open("input.txt") as file:
|
|
for line in file:
|
|
_line = line.strip()
|
|
(a, b) = map(str.strip, _line.split("contain"))
|
|
parent = a[:-1]
|
|
c = list(map(str.strip, b.split(",")))
|
|
children = []
|
|
for child in c:
|
|
cleaned = child.replace("bags", "bag").replace(".", "")
|
|
children += CHILD_PARSE.findall(cleaned)
|
|
PARSED_DICT[parent] = children
|
|
|
|
|
|
def solve_p1() -> int:
|
|
|
|
def check_contain(start: str, goal: str) -> bool:
|
|
if start in PARSED_DICT:
|
|
for _, child in PARSED_DICT[start]:
|
|
if child == goal or check_contain(child, goal):
|
|
return True
|
|
return False
|
|
|
|
def check_all(name: str) -> set:
|
|
result = set()
|
|
for bag in PARSED_DICT.keys():
|
|
if check_contain(bag, name):
|
|
result.add(bag)
|
|
return result
|
|
|
|
return len(check_all("shiny gold bag"))
|
|
|
|
|
|
def solve_p2() -> int:
|
|
|
|
def count_contained(name: str) -> int:
|
|
result = 1
|
|
if name in PARSED_DICT:
|
|
for number, child in PARSED_DICT[name]:
|
|
result += int(number) * count_contained(child)
|
|
return result
|
|
|
|
return count_contained("shiny gold bag")-1 # sub 1 because the root counts as 0
|