diff --git a/src/lib.rs b/src/lib.rs index 402b2b61..39ad9693 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1697,6 +1697,7 @@ pub mod problem_2272_substring_with_largest_variance; pub mod problem_2273_find_resultant_array_after_removing_anagrams; pub mod problem_2274_maximum_consecutive_floors_without_special_floors; pub mod problem_2275_largest_combination_with_bitwise_and_greater_than_zero; +pub mod problem_2276_count_integers_in_intervals; pub mod problem_2278_percentage_of_letter_in_string; pub mod problem_2279_maximum_bags_with_full_capacity_of_rocks; pub mod problem_2280_minimum_lines_to_represent_a_line_chart; diff --git a/src/problem_2276_count_integers_in_intervals/btree_map.rs b/src/problem_2276_count_integers_in_intervals/btree_map.rs new file mode 100644 index 00000000..c7973cd4 --- /dev/null +++ b/src/problem_2276_count_integers_in_intervals/btree_map.rs @@ -0,0 +1,86 @@ +// ------------------------------------------------------ snip ------------------------------------------------------ // + +use std::collections::BTreeMap; + +pub struct CountIntervals { + intervals: BTreeMap, + count: u32, + buffer: Vec, +} + +impl CountIntervals { + fn new() -> Self { + Self { + intervals: BTreeMap::new(), + count: 0, + buffer: Vec::new(), + } + } + + fn add(&mut self, left: i32, right: i32) { + let left = left as u32; + let mut right = right as u32 + 1; + + let mut to_remove_iter = self.intervals.range(left + 1..=right).map(|(&start, &end)| { + self.count -= end - start; + + (start, end) + }); + + if let Some((last_start, last_end)) = to_remove_iter.next_back() { + self.buffer.extend(to_remove_iter.map(|(start, _)| start)); + + for &start in &self.buffer { + self.intervals.remove(&start); + } + + self.intervals.remove(&last_start); + + self.buffer.clear(); + + right = right.max(last_end); + } + + if let Some(previous_node) = self.intervals.range_mut(..=left).next_back() { + if *previous_node.1 >= left { + if *previous_node.1 < right { + self.count += right - *previous_node.1; + *previous_node.1 = right; + } + + return; + } + } + + self.count += right - left; + self.intervals.insert(left, right); + } + + fn count(&self) -> i32 { + self.count as _ + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::CountIntervals for CountIntervals { + fn new() -> Self { + Self::new() + } + + fn add(&mut self, left: i32, right: i32) { + self.add(left, right); + } + + fn count(&self) -> i32 { + self.count() + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_2276_count_integers_in_intervals/mod.rs b/src/problem_2276_count_integers_in_intervals/mod.rs new file mode 100644 index 00000000..6d9370a1 --- /dev/null +++ b/src/problem_2276_count_integers_in_intervals/mod.rs @@ -0,0 +1,175 @@ +pub mod btree_map; + +pub trait CountIntervals { + fn new() -> Self; + fn add(&mut self, left: i32, right: i32); + fn count(&self) -> i32; +} + +#[cfg(test)] +mod tests { + use super::CountIntervals; + + enum Operation { + Add(i32, i32), + Count(i32), + } + + const EXTRA_TEST_CASE: &[Operation] = &[ + Operation::Count(0), + Operation::Count(0), + Operation::Add(571, 770), + Operation::Count(200), + Operation::Count(200), + Operation::Add(920, 996), + Operation::Count(277), + Operation::Count(277), + Operation::Count(277), + Operation::Count(277), + Operation::Count(277), + Operation::Add(65, 512), + Operation::Count(725), + Operation::Count(725), + Operation::Add(959, 959), + Operation::Count(725), + Operation::Add(313, 330), + Operation::Add(473, 928), + Operation::Count(932), + Operation::Count(932), + Operation::Add(75, 561), + Operation::Add(107, 835), + Operation::Add(852, 918), + Operation::Count(932), + Operation::Add(12, 774), + Operation::Add(534, 597), + Operation::Count(985), + Operation::Add(743, 776), + Operation::Add(456, 556), + Operation::Add(727, 750), + Operation::Add(403, 954), + Operation::Add(342, 803), + Operation::Add(299, 807), + Operation::Count(985), + Operation::Count(985), + Operation::Add(905, 951), + Operation::Add(365, 686), + Operation::Add(211, 646), + Operation::Add(185, 216), + Operation::Add(826, 910), + Operation::Count(985), + Operation::Count(985), + Operation::Add(470, 501), + Operation::Count(985), + Operation::Add(775, 959), + Operation::Count(985), + Operation::Count(985), + Operation::Add(343, 647), + Operation::Add(618, 743), + Operation::Add(203, 208), + Operation::Count(985), + Operation::Count(985), + Operation::Add(924, 962), + Operation::Count(985), + Operation::Count(985), + Operation::Add(307, 976), + Operation::Count(985), + Operation::Add(465, 831), + Operation::Count(985), + Operation::Add(411, 598), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Add(351, 936), + Operation::Add(209, 323), + Operation::Count(985), + Operation::Add(69, 194), + Operation::Add(419, 794), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Add(745, 962), + Operation::Count(985), + Operation::Add(613, 690), + Operation::Count(985), + Operation::Add(442, 520), + Operation::Add(259, 500), + Operation::Add(39, 272), + Operation::Count(985), + Operation::Count(985), + Operation::Count(985), + Operation::Add(160, 853), + Operation::Count(985), + Operation::Add(451, 519), + Operation::Count(985), + Operation::Count(985), + Operation::Add(363, 909), + Operation::Add(6, 770), + Operation::Add(819, 950), + Operation::Count(991), + Operation::Count(991), + Operation::Count(991), + Operation::Count(991), + Operation::Count(991), + Operation::Add(865, 891), + Operation::Count(991), + Operation::Add(630, 984), + Operation::Add(863, 966), + Operation::Add(385, 497), + Operation::Add(882, 885), + Operation::Count(991), + Operation::Add(906, 930), + Operation::Add(705, 717), + Operation::Count(991), + Operation::Add(654, 856), + Operation::Count(991), + Operation::Count(991), + Operation::Add(60, 693), + Operation::Add(666, 740), + Operation::Count(991), + Operation::Add(721, 899), + Operation::Add(347, 438), + Operation::Count(991), + Operation::Add(811, 994), + Operation::Add(67, 81), + Operation::Add(737, 898), + Operation::Count(991), + Operation::Count(991), + Operation::Count(991), + Operation::Add(7, 664), + Operation::Add(104, 796), + Operation::Add(487, 866), + Operation::Count(991), + ]; + + pub fn run() { + let test_cases = [ + &[ + Operation::Add(2, 3), + Operation::Add(7, 10), + Operation::Count(6), + Operation::Add(5, 8), + Operation::Count(8), + ] as &[_], + EXTRA_TEST_CASE, + ]; + + for operations in test_cases { + let mut count_intervals = C::new(); + + for operation in operations { + match *operation { + Operation::Add(left, right) => count_intervals.add(left, right), + Operation::Count(expected) => assert_eq!(count_intervals.count(), expected), + } + } + } + } +}