Using breadth first search!
This commit is contained in:
@@ -1,64 +1,52 @@
|
|||||||
class Bag():
|
|
||||||
def __init__(self, color):
|
|
||||||
self.color = color
|
|
||||||
self.children = []
|
|
||||||
|
|
||||||
def append(self, child):
|
|
||||||
self.children.append(child)
|
|
||||||
|
|
||||||
def count(self):
|
|
||||||
if not self.children:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
return sum([child.count() for child in self.children]) + 1
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"{self.color} -> {self.children}"
|
|
||||||
|
|
||||||
|
|
||||||
def process_rules(data):
|
def process_rules(data):
|
||||||
rules = {}
|
rules = {}
|
||||||
for rule in data:
|
for line in data:
|
||||||
color, rule = [r.strip() for r in rule.split("contain")]
|
line = line.replace(' bags', '').replace(' bag', '').replace('.', '')
|
||||||
|
color, rule = [r.strip() for r in line.split('contain ')]
|
||||||
|
rule = rule.split(', ')
|
||||||
|
|
||||||
color = color.replace('bags', '').strip()
|
rules[color] = []
|
||||||
rule = rule.replace('.', '').split(', ')
|
|
||||||
|
|
||||||
rules[color] = {}
|
|
||||||
for bag in rule:
|
for bag in rule:
|
||||||
if bag == 'no other bags': break
|
if bag == 'no other': break
|
||||||
|
rules[color].append((bag[2:], int(bag[0])))
|
||||||
amount = int(bag[0])
|
|
||||||
bag = bag[1:].replace('bags', '').replace('bag', '').strip()
|
|
||||||
|
|
||||||
rules[color][bag] = amount
|
|
||||||
|
|
||||||
return rules
|
return rules
|
||||||
|
|
||||||
def find_in_bag(bag, color, rules):
|
|
||||||
if color in rules[bag]: return True
|
|
||||||
if not rules[bag]: return False
|
|
||||||
|
|
||||||
return any([find_in_bag(bag, color, rules) for bag in rules[bag]])
|
def find_in_bags(color, rules):
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
for bag in rules:
|
||||||
|
discovered = []
|
||||||
|
discovered.extend(rules[bag])
|
||||||
|
|
||||||
|
while discovered:
|
||||||
|
x, _ = discovered.pop(0)
|
||||||
|
if x == 'shiny gold':
|
||||||
|
count += 1
|
||||||
|
break
|
||||||
|
discovered.extend(rules[x])
|
||||||
|
|
||||||
def create_bag_tree(bag, rules):
|
return count
|
||||||
for rule in rules[bag.color]:
|
|
||||||
for _ in range(rules[bag.color][rule]):
|
|
||||||
child = create_bag_tree(Bag(rule), rules)
|
|
||||||
bag.append(child)
|
|
||||||
|
|
||||||
return bag
|
def count_bags(bag, rules):
|
||||||
|
discovered = [bag]
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
while discovered:
|
||||||
|
bag, amount = discovered.pop(0)
|
||||||
|
for x, x_amt in rules[bag]:
|
||||||
|
discovered.append((x, amount * x_amt))
|
||||||
|
total += amount
|
||||||
|
|
||||||
|
return total - 1
|
||||||
|
|
||||||
|
|
||||||
def solve_a(rules):
|
def solve_a(rules):
|
||||||
bags = ([bag for bag in rules if find_in_bag(bag, "shiny gold", rules)])
|
return find_in_bags("shiny gold", rules)
|
||||||
return len(bags)
|
|
||||||
|
|
||||||
def solve_b(rules):
|
def solve_b(rules):
|
||||||
bag = create_bag_tree(Bag("shiny gold"), rules)
|
return count_bags(("shiny gold", 1), rules)
|
||||||
return bag.count()
|
|
||||||
|
|
||||||
|
|
||||||
data = [line.strip() for line in open('input')]
|
data = [line.strip() for line in open('input')]
|
||||||
|
|||||||
Reference in New Issue
Block a user