1use crate::util::iter::*;
14use crate::util::parse::*;
15use std::ops::Range;
16
17type Input = (Vec<Range<u64>>, Vec<u64>);
18
19pub fn parse(input: &str) -> Input {
20 let (prefix, suffix) = input.split_once("\n\n").unwrap();
21 let mut ranges: Vec<_> = prefix.iter_unsigned().chunk::<2>().collect();
22 let mut ids: Vec<_> = suffix.iter_unsigned().collect();
23 let mut range = 0..0;
24 let mut merged = Vec::new();
25
26 ranges.sort_unstable();
27 ids.sort_unstable();
28
29 for [from, to] in ranges {
31 if from < range.end {
32 range.end = range.end.max(to + 1);
33 } else {
34 merged.push(range);
35 range = from..to + 1;
36 }
37 }
38
39 merged.push(range);
40 (merged, ids)
41}
42
43pub fn part1(input: &Input) -> usize {
44 let (merged, ids) = input;
45 let position = |id: u64| ids.binary_search(&id).unwrap_or_else(|e| e);
46 merged.iter().map(|range| position(range.end) - position(range.start)).sum()
47}
48
49pub fn part2(input: &Input) -> u64 {
50 let (merged, _) = input;
51 merged.iter().map(|range| range.end - range.start).sum()
52}