patterns: HashSet::<&'a str>,
designs: Vec<&'a str>,
memo: HashMap<&'a str, u64>,
- n_valid: u64,
}
impl<'a> Puzzle<'a> {
let patterns = patterns.split(", ").collect();
let designs = designs.lines().collect();
let memo = HashMap::new();
- let n_valid = 0;
- Self { patterns, designs, memo, n_valid }
+ Self { patterns, designs, memo }
}
- fn is_valid_design(&self, design: &str) -> bool {
+ fn is_valid_design(&mut self, design: &'a str) -> bool {
if design.is_empty() {
return true
}
-
- for i in 0..design.len() {
- if self.patterns.contains(&design[0..=i]) &&
- self.is_valid_design(&design[(i+1)..design.len()])
- {
- return true;
- }
- }
- false
- }
-
- fn all_valid_design(&mut self, design: &'a str) -> bool {
- if let Some(n) = self.memo.get(design) {
- self.n_valid += n;
+ if self.memo.contains_key(design) {
return true;
}
- if design.is_empty() {
- self.n_valid += 1;
- return true
- }
- let mut n = 0;
+ let mut n_ways = 0;
let mut is_valid = false;
for i in 0..design.len() {
if self.patterns.contains(&design[0..=i]) &&
- self.all_valid_design(&design[(i+1)..design.len()])
+ self.is_valid_design(&design[(i+1)..design.len()])
{
- n += match self.memo.get(&design[(i+1)..design.len()]) {
+ n_ways += match self.memo.get(&design[(i+1)..design.len()]) {
Some(m) => *m,
None => 1
};
}
}
- self.memo.insert(design, n);
+ self.memo.insert(design, n_ways);
is_valid
}
fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
println!("Running {} - part 1", get_day());
- let puzzle = Puzzle::new(input);
- let res = puzzle.designs.iter()
+ let mut puzzle = Puzzle::new(input);
+ let res = puzzle.designs.clone().iter()
.filter(|d| puzzle.is_valid_design(d))
.count() as u32;
let mut puzzle = Puzzle::new(input);
puzzle.designs.clone().iter()
- .for_each(|d| { puzzle.all_valid_design(d); });
-
- let res = puzzle.n_valid;
+ .for_each(|d| { puzzle.is_valid_design(d); });
+ let res: u64 = puzzle.designs.clone().iter()
+ .filter_map(|d| puzzle.memo.get(d))
+ .sum();
Ok(res)
}