diff --git a/src/lib.rs b/src/lib.rs index 969c8da1..86ff70a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1530,6 +1530,7 @@ pub mod problem_2094_finding_3_digit_even_numbers; pub mod problem_2095_delete_the_middle_node_of_a_linked_list; pub mod problem_2096_step_by_step_directions_from_a_binary_tree_node_to_another; pub mod problem_2099_find_subsequence_of_length_k_with_the_largest_sum; +pub mod problem_2100_find_good_days_to_rob_the_bank; pub mod problem_2103_rings_and_rods; pub mod problem_2108_find_first_palindromic_string_in_the_array; pub mod problem_2109_adding_spaces_to_a_string; diff --git a/src/problem_2100_find_good_days_to_rob_the_bank/mod.rs b/src/problem_2100_find_good_days_to_rob_the_bank/mod.rs new file mode 100644 index 00000000..a3e6fb10 --- /dev/null +++ b/src/problem_2100_find_good_days_to_rob_the_bank/mod.rs @@ -0,0 +1,24 @@ +pub mod sliding_window; + +pub trait Solution { + fn good_days_to_rob_bank(security: Vec, time: i32) -> Vec; +} + +#[cfg(test)] +mod tests { + use super::Solution; + + pub fn run() { + let test_cases = [ + ((&[5, 3, 3, 3, 5, 6, 2] as &[_], 2), &[2, 3] as &[_]), + ((&[1, 1, 1, 1, 1], 0), &[0, 1, 2, 3, 4]), + ((&[1, 2, 3, 4, 5, 6], 2), &[]), + ((&[1, 2, 5, 4, 1, 0, 2, 4, 5, 3, 1, 2, 4, 3, 2, 4, 8], 2), &[5, 10, 14]), + ((&[1], 5), &[]), + ]; + + for ((security, time), expected) in test_cases { + assert_eq!(S::good_days_to_rob_bank(security.to_vec(), time), expected); + } + } +} diff --git a/src/problem_2100_find_good_days_to_rob_the_bank/sliding_window.rs b/src/problem_2100_find_good_days_to_rob_the_bank/sliding_window.rs new file mode 100644 index 00000000..d68a8b14 --- /dev/null +++ b/src/problem_2100_find_good_days_to_rob_the_bank/sliding_window.rs @@ -0,0 +1,81 @@ +pub struct Solution; + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl Solution { + pub fn good_days_to_rob_bank(security: Vec, time: i32) -> Vec { + let security = security.into_iter().map(|x| x as u32).collect::>(); + let time = time as u32 as usize; + let mut result = Vec::new(); + + if security.len() > time * 2 { + let (first_chunk, rest) = security.split_at(time); + let (second_chunk, third_chunk) = rest.split_at(time); + let mut left_length = 0; + let mut left_prev = 0; + + for &value in first_chunk.iter().rev() { + if value < left_prev { + break; + } + + left_length += 1; + left_prev = value; + } + + let mut right_length = 0; + let mut right_prev = u32::MAX; + + for &value in second_chunk.iter().rev() { + if value > right_prev { + break; + } + + right_length += 1; + right_prev = value; + } + + right_prev = security.get((time * 2).wrapping_sub(1)).copied().unwrap_or(u32::MAX); + + for (day, (&left, &right)) in (time as u32..).zip(rest.iter().zip(third_chunk)) { + if left_prev < left { + left_length = 1; + } else { + left_length += 1; + } + + left_prev = left; + + if right < right_prev { + right_length = 1; + } else { + right_length += 1; + } + + right_prev = right; + + if left_length > time as u32 && right_length > time as u32 { + result.push(day as _); + } + } + } + + result + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::Solution for Solution { + fn good_days_to_rob_bank(security: Vec, time: i32) -> Vec { + Self::good_days_to_rob_bank(security, time) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +}