-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Implement Trapped Rain Water Problem #712
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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
8c92d25
chore: add `trapped_rainwater.rs` to DIRECTORY.md
sozelfist ca0947e
feat: implement Trapped Rain Water algorithm
sozelfist c207d30
chore: add tests
sozelfist 41a41e9
chore: rename `height` to `elevation_map`
sozelfist d505150
ref: change `Vec<u32` to `[u32]`
sozelfist dc1987f
ref: refactor implementation
sozelfist ce05eb5
tests: add more test cases
vil02 4110e15
style: simplify logic by reducing redundant branch
vil02 c2f9c3a
Merge branch 'master' into dp/trapped_rainwater
vil02 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
//! Module to calculate trapped rainwater in an elevation map. | ||
|
||
/// Computes the total volume of trapped rainwater in a given elevation map. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `elevation_map` - A slice containing the heights of the terrain elevations. | ||
/// | ||
/// # Returns | ||
/// | ||
/// The total volume of trapped rainwater. | ||
pub fn trapped_rainwater(elevation_map: &[u32]) -> u32 { | ||
let left_max = calculate_max_values(elevation_map, false); | ||
let right_max = calculate_max_values(elevation_map, true); | ||
let mut water_trapped = 0; | ||
// Calculate trapped water | ||
for i in 0..elevation_map.len() { | ||
water_trapped += left_max[i].min(right_max[i]) - elevation_map[i]; | ||
} | ||
water_trapped | ||
} | ||
|
||
/// Determines the maximum heights from either direction in the elevation map. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `elevation_map` - A slice representing the heights of the terrain elevations. | ||
/// * `reverse` - A boolean that indicates the direction of calculation. | ||
/// - `false` for left-to-right. | ||
/// - `true` for right-to-left. | ||
/// | ||
/// # Returns | ||
/// | ||
/// A vector containing the maximum heights encountered up to each position. | ||
fn calculate_max_values(elevation_map: &[u32], reverse: bool) -> Vec<u32> { | ||
let mut max_values = vec![0; elevation_map.len()]; | ||
let mut current_max = 0; | ||
for i in create_iter(elevation_map.len(), reverse) { | ||
current_max = current_max.max(elevation_map[i]); | ||
max_values[i] = current_max; | ||
} | ||
max_values | ||
} | ||
|
||
/// Creates an iterator for the given length, optionally reversing it. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `len` - The length of the iterator. | ||
/// * `reverse` - A boolean that determines the order of iteration. | ||
/// - `false` for forward iteration. | ||
/// - `true` for reverse iteration. | ||
/// | ||
/// # Returns | ||
/// | ||
/// A boxed iterator that iterates over the range of indices. | ||
fn create_iter(len: usize, reverse: bool) -> Box<dyn Iterator<Item = usize>> { | ||
if reverse { | ||
Box::new((0..len).rev()) | ||
} else { | ||
Box::new(0..len) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
macro_rules! trapped_rainwater_tests { | ||
($($name:ident: $test_case:expr,)*) => { | ||
$( | ||
#[test] | ||
fn $name() { | ||
let (elevation_map, expected_trapped_water) = $test_case; | ||
assert_eq!(trapped_rainwater(&elevation_map), expected_trapped_water); | ||
let elevation_map_rev: Vec<u32> = elevation_map.iter().rev().cloned().collect(); | ||
assert_eq!(trapped_rainwater(&elevation_map_rev), expected_trapped_water); | ||
} | ||
)* | ||
}; | ||
} | ||
|
||
trapped_rainwater_tests! { | ||
test_trapped_rainwater_basic: ( | ||
[0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1], | ||
6 | ||
), | ||
sozelfist marked this conversation as resolved.
Show resolved
Hide resolved
vil02 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
test_trapped_rainwater_peak_under_water: ( | ||
[3, 0, 2, 0, 4], | ||
7, | ||
), | ||
test_bucket: ( | ||
[5, 1, 5], | ||
4 | ||
), | ||
test_skewed_bucket: ( | ||
[4, 1, 5], | ||
3 | ||
), | ||
test_trapped_rainwater_empty: ( | ||
[], | ||
0 | ||
), | ||
test_trapped_rainwater_flat: ( | ||
[0, 0, 0, 0, 0], | ||
0 | ||
), | ||
test_trapped_rainwater_no_trapped_water: ( | ||
[1, 1, 2, 4, 0, 0, 0], | ||
0 | ||
), | ||
test_trapped_rainwater_single_elevation_map: ( | ||
[5], | ||
0 | ||
), | ||
vil02 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
test_trapped_rainwater_two_point_elevation_map: ( | ||
[5, 1], | ||
0 | ||
), | ||
test_trapped_rainwater_large_elevation_map_difference: ( | ||
[5, 1, 6, 1, 7, 1, 8], | ||
15 | ||
), | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.