]> aoc.elinar.fr Git - aoc_2025/commitdiff
day05: part2
authoralex <>
Fri, 5 Dec 2025 15:17:24 +0000 (16:17 +0100)
committeralex <>
Fri, 5 Dec 2025 15:17:24 +0000 (16:17 +0100)
src/day05.rs

index a37f58cc6c0377077f876a729c1a4082b930a9e5..8af625dd7ca4ae6d5d935c75ca8a51874de1ab57 100644 (file)
@@ -27,11 +27,71 @@ impl Puzzle {
             .filter(|v| self.ranges.iter().any(|r| r.contains(v)))
             .count()
     }
+
+    fn update_ranges(&mut self) {
+        // keep track of the ranges
+        // if the current one is partly in a dst one => upate the remote
+        // if the current one is contained in remote => do nothing
+        // if the current one contains a remote one => update the remote
+        // add to remote/dst
+        let mut ranges: Vec::<RangeInclusive<u64>> = Vec::new();
+        self.ranges.iter()
+            .enumerate()
+            .for_each(|(i, r)| {
+                let (a,b) = (r.start(), r.end());
+                // - a is in a RangeInclusive
+                //      - b too
+                //          => remove the current range
+                //      - else update the max value of the RangeInclusive
+                // - else
+                //      - b is within a RangeInclusive
+                //          => update the min value of the RangeInclusive
+                //      - else, add a new RangeInclusive a..=b
+                match ranges.iter().enumerate().position(|(j,r)| j != i && r.contains(a)) {
+                    Some(p) => {
+                        if !ranges[p].contains(b) {
+                            ranges[p] = *ranges[p].start()..=*b;
+                        }
+                    },
+                    None => {
+                        match ranges.iter().enumerate().position(|(j,r)| j != i && r.contains(b)) {
+                            Some(p) => { ranges[p] = *a..=*ranges[p].end(); },
+                            None => {
+                                // maybe there is a dst RangeInclusive that is between a and b
+                                match ranges.iter().enumerate()
+                                        .position(|(j,r)| {
+                                            let (a1, b1) = (r.start(), r.end());
+                                            j != i && a < a1 && b1 < b
+                                        }) {
+                                            Some(p) => { ranges[p] = *a..=*b; },
+                                            None => { ranges.push(*a..=*b); },
+                                        }
+                            }
+                        }
+                    },
+                }
+            });
+        if ranges != self.ranges {
+            self.ranges = ranges;
+            self.update_ranges();
+        }
+    }
+
+    fn part2(&mut self) -> u64 {
+        self.update_ranges();
+        self.ranges.iter()
+            .map(|r| {
+                let (a,b) = (r.start(), r.end());
+                b - a + 1
+            })
+            .sum()
+    }
 }
 
 pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
-    let p = Puzzle::new(input);
+    let mut p = Puzzle::new(input);
     println!("part1: {}", p.part1());
+    println!("part2: {}", p.part2());
     Ok(())
 }
 
@@ -52,8 +112,25 @@ mod tests {
 17
 32";
 
+    static INPUT_2: &str = "\
+3-5
+10-14
+16-20
+12-18
+9-21
+
+1";
+
     #[test]
     fn test_part1() {
         assert_eq!(3, Puzzle::new(INPUT).part1());
     }
+    #[test]
+    fn test_part2() {
+        assert_eq!(14, Puzzle::new(INPUT).part2());
+    }
+    #[test]
+    fn test_part2_1() {
+        assert_eq!(16, Puzzle::new(INPUT_2).part2());
+    }
 }