<jupyter_start><jupyter_text>Day 7How many bags can fit a shiny golden bag?<jupyter_code>import re

file7 = open('day7_input', 'r') 
input7_lines = file7.readlines()
for idx, line in enumerate(input7_lines):
    print(idx, line)
a=input7_lines[0]
a
s1 = re.sub(r'[^\w]', ' ', a)
s2 = re.split(r'\s', s1)
b = [s for s in s2 if s not in ignore_cases]
' '.join(b[2:3:])
b=['a', 'b']
b[2:]
ignore_cases = ['', 'bags', 'bag', 'contain', 'no', 'other']
instructions = []
possible_colors_bag = set([])
possible_colors_contains = set([])
for line in input7_lines:
    
    #this_bag_instruct_list = line.replace('\n', '').replace(',', '').replace('.', '').replace('contain ', '').replace('bags', 'piet').replace('bag', 'bags').replace('piet', 'bags').split(' bags')
    # Replace all symbols in string to free space.
    line_no_symbols = re.sub(r'[^\w]', ' ', line)
    # Split string into words, removing ignore_cases.
    this_bag_instruct_list = [word for word in re.split(r'\s', line_no_symbols) if word not in ignore_cases]
    this_bag_instruct_list = np.array(this_bag_instruct_list)
    
    this_bag = ' '.join(this_bag_instruct_list[:2])
    possible_colors_bag.add(this_bag)
    
    contains = []
    if len(this_bag_instruct_list[2:]) == 0:
        continue
    else:
        inside_instructs = this_bag_instruct_list[2:].reshape(-1,3)
        
    for instruct in inside_instructs:
        bag_color = ' '.join(instruct[1:])
        #print('_' + instruct + '_')
        contains.append((int(instruct[0]), bag_color))    
        possible_colors_contains.add(bag_color)
        
    instructions.append([this_bag, contains])
    
# Obtain all possible colors and sort the list.
all_colors = list(possible_colors_bag)
all_colors.sort()

# Make mapping of color name to color index. 
color_to_index = dict(zip(all_colors, range(len(all_colors))))
# Set index of shiny gold bag
shiny_gold_index = color_to_index['shiny gold']
np.setdiff1d(list(possible_colors_contains), list(possible_colors_bag))
substitute_colors = np.zeros((len(all_colors), len(all_colors)))#.astype(np.float)
# array indexing: row:column
for (this_color, contains) in instructions:
    if len(contains) == 0:
        #print(contains)
        continue
    #print(contains, len(contains))
    for (contains_nbr, contains_color) in contains:
        substitute_colors[color_to_index[this_color], color_to_index[contains_color]] = 1
this_bag_contains_after_n_subs = np.eye(len(all_colors))#.astype(np.int)
bags_that_can_contain_shiny_gold_idx = set([])
for idx in range(1000):
    %time this_bag_contains_after_n_subs = this_bag_contains_after_n_subs.dot(substitute_colors) 
    this_bag_contains_after_n_subs[ this_bag_contains_after_n_subs > 1 ] = 1
    
    all_bags_containing_shiny_gold = this_bag_contains_after_n_subs.T[shiny_gold_index]
    if all_bags_containing_shiny_gold.sum() > 0:
        all_bags_containing_shiny_gold_idx = np.where(all_bags_containing_shiny_gold)[0]
        [bags_that_can_contain_shiny_gold_idx.add(bag_idx) for bag_idx in all_bags_containing_shiny_gold_idx]
     
    print(idx, this_bag_contains_after_n_subs.sum(), all_bags_containing_shiny_gold.sum())
    if this_bag_contains_after_n_subs.sum() == 0:
        break<jupyter_output><empty_output><jupyter_text>Concept of matrix multiplications<jupyter_code>trs = np.array([[0, 1, 0],
                [0, 0, 1],
                [1, 0, 0]])
a = np.eye(3).astype(np.int)

b = a.dot(trs)
b
c = b.dot(trs)
c
[all_colors[idx] for idx in list(bags_that_can_contain_shiny_gold_idx)]
answer7A=len(bags_that_can_contain_shiny_gold_idx)
print(answer7A)<jupyter_output>151<jupyter_text>Part BGiven that you have a shiny gold bag, how many bags are inside?<jupyter_code>substitute_colors_number = np.zeros((len(all_colors), len(all_colors))).astype(np.int)
# array indexing: row:column
for (this_color, contains) in instructions:
    if len(contains) == 0:
        #print(contains)
        continue
    #print(contains, len(contains))
    for (contains_nbr, contains_color) in contains:
        substitute_colors_number[color_to_index[this_color], color_to_index[contains_color]] = contains_nbr
this_bag_contains_after_n_subs = np.eye(len(all_colors)).astype(np.int)
number_of_bags_inside_shiny_gold = 0

for idx in range(1000):
    this_bag_contains_after_n_subs = this_bag_contains_after_n_subs.dot(substitute_colors_number)
    #this_bag_contains_after_n_subs[ this_bag_contains_after_n_subs > 1 ] = 1
    
    all_bags_inside_shiny_gold_bag_level_n = this_bag_contains_after_n_subs[shiny_gold_index]
    number_of_bags_inside_shiny_gold += all_bags_inside_shiny_gold_bag_level_n.sum()
     
    print(idx, all_bags_inside_shiny_gold_bag_level_n.sum(), number_of_bags_inside_shiny_gold)
    if this_bag_contains_after_n_subs.sum() == 0:
        break<jupyter_output>0 5 5
1 61 66
2 171 237
3 666 903
4 3300 4203
5 8340 12543
6 22536 35079
7 6480 41559
8 0 41559
9 0 41559
10 0 41559
11 0 41559
12 0 41559
13 0 41559
14 0 41559
15 0 41559
16 0 41559
17 0 41559
18 0 41559
19 0 41559
20 0 41559
21 0 41559
22 0 41559
{'fraction_non_alphanumeric': 0.11497431845120505, 'fraction_numerical': 0.047412090082971155, 'mean_word_length': 4.806192660550459, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '19225', 'license': 'MIT', 'n_tokens_mistral': 2101, 'n_tokens_neox': 1893, 'n_words': 377, 'path': 'day7.ipynb', 'repo_name': 'Paijmans/advent_of_code', 'size': '5062'}