Skip to content

Commit

Permalink
Add problem 2276: Count Integers in Intervals
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Nov 4, 2024
1 parent 07e5dc3 commit 8f66cfe
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
86 changes: 86 additions & 0 deletions src/problem_2276_count_integers_in_intervals/btree_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::collections::BTreeMap;

pub struct CountIntervals {
intervals: BTreeMap<u32, u32>,
count: u32,
buffer: Vec<u32>,
}

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::<super::CountIntervals>();
}
}
175 changes: 175 additions & 0 deletions src/problem_2276_count_integers_in_intervals/mod.rs
Original file line number Diff line number Diff line change
@@ -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<C: CountIntervals>() {
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),
}
}
}
}
}

0 comments on commit 8f66cfe

Please sign in to comment.