# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python [conda env:stats_env]
#     language: python
#     name: conda-env-stats_env-py
# ---

# # Day 7

# ! cat README.md

with open('input.txt', 'rt') as f:
    l = f.read().splitlines()


# +
def parse_item(item):

    key, value = item.split(' contain ')
    container = ' '.join(key.split(' ')[:2])
    if value.endswith('no other bags.'):
        content = {}
    else:
        content = dict(map(lambda x: (' '.join(x.split(' ')[1:3]), 
                                  int(x.split(' ')[0])),
                           value.rstrip('.').split(', ')))
    return (container, content)

input_dict = dict(list(map(parse_item, l)))
# -

container_dict = {}
for k, v in input_dict.items():
    for w in v:
        container_dict[w] = container_dict.get(w, []) + [k]

possible_containers = []
queue = ['shiny gold']
while len(queue) > 0:
    k = queue.pop(0)
    if k not in container_dict:
        continue
    for c in container_dict[k]:
        if c not in possible_containers:
            possible_containers.append(c)
            queue.append(c)
        elif c in possible_containers:
            continue

len(possible_containers)

# --- Part Two ---
# It's getting pretty expensive to fly these days - not because of ticket prices, but because of the ridiculous number of bags you need to buy!
#
# Consider again your shiny gold bag and the rules from the above example:
#
# faded blue bags contain 0 other bags.
# dotted black bags contain 0 other bags.
# vibrant plum bags contain 11 other bags: 5 faded blue bags and 6 dotted black bags.
# dark olive bags contain 7 other bags: 3 faded blue bags and 4 dotted black bags.
# So, a single shiny gold bag must contain 1 dark olive bag (and the 7 bags within it) plus 2 vibrant plum bags (and the 11 bags within each of those): 1 + 1*7 + 2 + 2*11 = 32 bags!
#
# Of course, the actual rules have a small chance of going several levels deeper than this example; be sure to count all of the bags, even if the nesting becomes topologically impractical!
#
# Here's another example:
#
# shiny gold bags contain 2 dark red bags.
# dark red bags contain 2 dark orange bags.
# dark orange bags contain 2 dark yellow bags.
# dark yellow bags contain 2 dark green bags.
# dark green bags contain 2 dark blue bags.
# dark blue bags contain 2 dark violet bags.
# dark violet bags contain no other bags.
# In this example, a single shiny gold bag must contain 126 other bags.
#
# How many individual bags are required inside your single shiny gold bag?

# +
# test

test_dict = {'shiny gold': {'dark red': 2},
             'dark red': {'dark orange': 2},
             'dark orange': {'dark yellow': 2},
             'dark yellow': {'dark green': 2},
             'dark green': {'dark blue': 2},
             'dark blue': {'dark violet': 2},
             'dark violet': {}}
# -

bag_count = 0
queue = [('shiny gold', 1)]
while len(queue) > 0:
    color, factor = queue.pop(0)
    bag_count += factor
    for k, v in input_dict[color].items():
        queue.append((k, factor * v))

bag_count - 1

StarcoderdataJupyterScriptsDedupFiltered