.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(())
}
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());
+ }
}