diff --git a/aoc2020/src/day07.rs b/aoc2020/src/day07.rs index ec03766..a2e9a8c 100644 --- a/aoc2020/src/day07.rs +++ b/aoc2020/src/day07.rs @@ -28,9 +28,11 @@ fn part1(input: &str) -> aoc::Result { .map(|bag_rule| (bag_rule.color.clone(), bag_rule.clone())) .collect(); + let mut memoized = HashMap::new(); + Ok(bag_rules .iter() - .filter(|bag| bag.can_contain("shiny gold", &bag_rules_map)) + .filter(|bag| bag.can_contain("shiny gold", &bag_rules_map, &mut memoized)) .count()) } @@ -59,17 +61,28 @@ struct BagRule { } impl BagRule { - fn can_contain(&self, color: &str, all_bags: &HashMap) -> bool { - if self.contains.iter().any(|(_, c)| c == color) { - return true; - } + fn can_contain( + &self, + color: &str, + all_bags: &HashMap, + memoized: &mut HashMap, + ) -> bool { + return match memoized.get(&self.color) { + Some(value) => *value, + None => { + let value = self.contains.iter().any(|(_, c)| c == color) + || self.contains.iter().any(|(_, c)| { + // fetch rules for this bag in map + let bag_rule = &all_bags[c]; - self.contains.iter().any(|(_, c)| { - // fetch rules for this bag in map - let bag_rule = &all_bags[c]; + bag_rule.can_contain(color, all_bags, memoized) + }); - bag_rule.can_contain(color, all_bags) - }) + memoized.insert(self.color.clone(), value); + + value + } + }; } fn num_inner_bags(&self, all_bags: &HashMap) -> usize {