]> aoc.elinar.fr Git - aoc_2024/commitdiff
Day19 - refactor
authoralex <>
Thu, 19 Dec 2024 15:45:48 +0000 (16:45 +0100)
committeralex <>
Thu, 19 Dec 2024 15:45:48 +0000 (16:45 +0100)
Use the same code for part 1 and 2.

src/day19.rs

index 172ba2455f86c2b95a24e315526d027d9862f902..368270dbc9c89b38b1e30ab14d2360ee7a109a4e 100644 (file)
@@ -6,7 +6,6 @@ struct Puzzle<'a> {
     patterns: HashSet::<&'a str>,
     designs: Vec<&'a str>,
     memo: HashMap<&'a str, u64>,
-    n_valid: u64,
 }
 
 impl<'a> Puzzle<'a> {
@@ -15,43 +14,25 @@ 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
                 };
@@ -59,7 +40,7 @@ impl<'a> Puzzle<'a> {
             }
         }
 
-        self.memo.insert(design, n);
+        self.memo.insert(design, n_ways);
 
         is_valid
     }
@@ -68,8 +49,8 @@ impl<'a> Puzzle<'a> {
 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;
 
@@ -81,9 +62,10 @@ fn run_part2(input: &str) -> Result<u64, Box<dyn Error>> {
 
     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)
 }