Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Trapped Rain Water Problem #712

Merged
merged 9 commits into from
May 18, 2024
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
* [Rod Cutting](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/rod_cutting.rs)
* [Snail](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/snail.rs)
* [Subset Generation](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/subset_generation.rs)
* [Trapped Rain Water](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/trapped_rainwater.rs)
* [Word Break](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/word_break.rs)
* General
* [Convex Hull](https://github.com/TheAlgorithms/Rust/blob/master/src/general/convex_hull.rs)
Expand Down
2 changes: 2 additions & 0 deletions src/dynamic_programming/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod minimum_cost_path;
mod rod_cutting;
mod snail;
mod subset_generation;
mod trapped_rainwater;
mod word_break;

pub use self::coin_change::coin_change;
Expand All @@ -41,4 +42,5 @@ pub use self::minimum_cost_path::minimum_cost_path;
pub use self::rod_cutting::rod_cut;
pub use self::snail::snail;
pub use self::subset_generation::list_subset;
pub use self::trapped_rainwater::trapped_rainwater;
pub use self::word_break::word_break;
83 changes: 83 additions & 0 deletions src/dynamic_programming/trapped_rainwater.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Module to calculate trapped rainwater in an elevation map.

/// Calculates the total amount of trapped rainwater in the given elevation map.
///
/// # Arguments
///
/// * `height` - A vector containing the heights of walls forming the elevation map.
///
/// # Returns
///
/// The total amount of trapped rainwater.
pub fn trapped_rainwater(height: Vec<u32>) -> u32 {
TruongNhanNguyen marked this conversation as resolved.
Show resolved Hide resolved
if height.is_empty() {
return 0;
}

let mut left_max = vec![0; height.len()];
let mut right_max = vec![0; height.len()];
let mut water_trapped = 0;

// Calculate left_max array
left_max[0] = height[0];
for i in 1..height.len() {
left_max[i] = left_max[i - 1].max(height[i]);
}

// Calculate right_max array
right_max[height.len() - 1] = height[height.len() - 1];
for i in (0..(height.len() - 1)).rev() {
right_max[i] = right_max[i + 1].max(height[i]);
}

// Calculate trapped water
for i in 0..height.len() {
water_trapped += left_max[i].min(right_max[i]) - height[i];
}
TruongNhanNguyen marked this conversation as resolved.
Show resolved Hide resolved

water_trapped
}

#[cfg(test)]
mod tests {
use super::*;

macro_rules! trapped_rainwater_tests {
($($name:ident: $test_case:expr,)*) => {
$(
#[test]
fn $name() {
let (height, expected_trapped_water) = $test_case;
assert_eq!(trapped_rainwater(height), expected_trapped_water);
}
)*
};
}

trapped_rainwater_tests! {
test_trapped_rainwater_basic: (
vec![0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1],
6
),
TruongNhanNguyen marked this conversation as resolved.
Show resolved Hide resolved
vil02 marked this conversation as resolved.
Show resolved Hide resolved
test_trapped_rainwater_empty: (
Vec::new(),
0
),
test_trapped_rainwater_flat: (
vec![0, 0, 0, 0, 0],
0
),
test_trapped_rainwater_no_trapped_water: (
vec![1, 1, 2, 4, 0, 0, 0],
0
),
test_trapped_rainwater_single_height: (
vec![5],
0
),
vil02 marked this conversation as resolved.
Show resolved Hide resolved
test_trapped_rainwater_large_height_difference: (
vec![5, 1, 6, 1, 7, 1, 8],
15
),
}
}