Day 7 of 2020 done in Python
This commit is contained in:
parent
9b505dc8d6
commit
259f691608
2 changed files with 700 additions and 0 deletions
105
2020/Day 7/Solution.py
Normal file
105
2020/Day 7/Solution.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
import re
|
||||
|
||||
bag_re = re.compile(r'(?:([a-z\s]+) bags contain)?(?:\s?([0-9]) ([a-z\s]+)\sbags?[,.])')
|
||||
|
||||
input_file = "input.txt"
|
||||
|
||||
|
||||
def find_bags_containing_bag(search_bag="shiny gold"):
|
||||
# Stores the bag colors that can store the bag in the key
|
||||
bag_relations = {}
|
||||
|
||||
with open(input_file) as rules:
|
||||
line = rules.readline()
|
||||
|
||||
while line and line != "\n":
|
||||
match = bag_re.findall(line)
|
||||
|
||||
if not match:
|
||||
line = rules.readline()
|
||||
continue
|
||||
|
||||
parent_bag = match[0][0]
|
||||
|
||||
for sub_match in match:
|
||||
|
||||
if sub_match[2] in bag_relations and parent_bag not in bag_relations[sub_match[2]]:
|
||||
bag_relations[sub_match[2]].append(parent_bag)
|
||||
else:
|
||||
bag_relations[sub_match[2]] = [parent_bag]
|
||||
|
||||
line = rules.readline()
|
||||
|
||||
explored_bags = []
|
||||
bags_to_explore = [search_bag]
|
||||
|
||||
usable_bags = 0
|
||||
|
||||
while len(bags_to_explore) > 0:
|
||||
current_exploration = bags_to_explore.pop(0)
|
||||
explored_bags.append(current_exploration)
|
||||
|
||||
if current_exploration not in bag_relations:
|
||||
continue
|
||||
|
||||
for bag in bag_relations[current_exploration]:
|
||||
if bag not in explored_bags and bag not in bags_to_explore:
|
||||
usable_bags += 1
|
||||
bags_to_explore.append(bag)
|
||||
|
||||
print(f"The number of bags that can contain a {search_bag} bag is {usable_bags}")
|
||||
|
||||
|
||||
def count_bags_contained_in_bag(search_bag="shiny gold"):
|
||||
# Stores the number of bags a bag directly contains
|
||||
bag_counts = {}
|
||||
# Stores the bags contained and how many of them
|
||||
bags_contained = {}
|
||||
|
||||
with open(input_file) as rules:
|
||||
line = rules.readline()
|
||||
|
||||
while line and line != "\n":
|
||||
match = bag_re.findall(line)
|
||||
|
||||
if not match:
|
||||
line = rules.readline()
|
||||
continue
|
||||
|
||||
parent_bag = match[0][0]
|
||||
|
||||
bags_contained[parent_bag] = []
|
||||
bag_counts[parent_bag] = 0
|
||||
|
||||
for sub_match in match:
|
||||
bag_counts[parent_bag] += int(sub_match[1])
|
||||
bags_contained[parent_bag].append((sub_match[2], int(sub_match[1])))
|
||||
|
||||
line = rules.readline()
|
||||
|
||||
explored_bags = []
|
||||
bags_to_explore = [(search_bag, 1)]
|
||||
|
||||
total_bags = 0
|
||||
|
||||
# For each bag, fetch the total amount of bag it contains and multiply it by the number of times
|
||||
# this bag has been counted. Then, add the contained bag to the list of bags to count while keeping track of
|
||||
# the multiplier.
|
||||
# For ex. : a bag contains two blue bags. The blue bags are added with a multiplier of two.
|
||||
# The blue bags contain each three red bags. Thus, we count six red bags and add them with a multiplier of six.
|
||||
while len(bags_to_explore) > 0:
|
||||
current_exploration = bags_to_explore.pop(0)
|
||||
explored_bags.append(current_exploration)
|
||||
|
||||
if current_exploration[0] not in bag_counts:
|
||||
continue
|
||||
|
||||
# Add the number of bags contained, multiplied by the number of times this has appeared in this "bag descent"
|
||||
total_bags += bag_counts[current_exploration[0]]*current_exploration[1]
|
||||
|
||||
for bag in bags_contained[current_exploration[0]]:
|
||||
# Keep track of the number of bags that appear in total by multiplying the number of bags
|
||||
# by the number of times the current bag appears in this "bag descent"
|
||||
bags_to_explore.append((bag[0], current_exploration[1]*bag[1]))
|
||||
|
||||
print(f"The total number of bags a {search_bag} contains {total_bags}")
|
Loading…
Add table
Add a link
Reference in a new issue