move to 2020 fodler

This commit is contained in:
2021-12-01 11:43:46 +01:00
parent eb251ac1ea
commit c651a48895
33 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
# 7
This one was maybe the coolest yet! Fixed-point iteration and some recursion. Amazing :)
For the first part we iterate as long as we don't find any enclosing bags anymore. This can build long chains.
The second we recurse down the bag chain und sum it up recursively.
<details>
<summary>Solutions</summary>
<ol>
<li>164</li>
<li>7872</li>
</ol>
</details>

View File

@@ -0,0 +1,70 @@
from os.path import join, dirname
from typing import Dict, List, Set, Tuple
import re
TRules = Dict[str, Dict[str, int]]
def split_trim(input: str, split: str) -> List[str]:
return list(map(lambda s: s.strip(), input.split(split)))
def extract_inner(input: str) -> Tuple[int, str]:
parts = input.split(' ')
amount = int(parts[0])
color = ' '.join(parts[1:-1])
return amount, color
def parse_rules(rules: str) -> TRules:
d: TRules = {}
for rule in rules.strip().split('\n'):
outer, inner = split_trim(rule, 'contain')
outer = re.sub(r'bags?', '', outer).strip()
d[outer] = {
color: amount
for amount, color in [
extract_inner(i)
for i in split_trim(inner, ',')
if 'no other bag' not in i # Also matches "bags"
]
}
return d
def find_enclosing_bags(rules: TRules, color: str) -> Set[str]:
colors: Set[str] = set()
stack: Set[str] = set([color])
while len(stack):
for item in list(stack):
stack.remove(item)
for contains, enclosing in rules.items():
if item in enclosing:
if contains not in colors:
stack.add(contains)
colors.add(contains)
return colors
def count_containing(rules: TRules, color: str) -> int:
children = rules[color]
if not children:
return 0
return sum([
amount + amount * count_containing(rules, clr)
for clr, amount in children.items()
])
data = join(dirname(__file__), '../data.txt')
with open(data) as f:
rules = parse_rules(f.read())
color = 'shiny gold'
first = len(find_enclosing_bags(rules, color))
print(f'We can pack the {color} into {first} bags')
second = count_containing(rules, color)
print(f'We need to put {second} bags into {color}')