Skip to content

Commit 6fc4299

Browse files
committedJul 27, 2018
Add Rain Terraces problem.
1 parent 3271ee9 commit 6fc4299

File tree

3 files changed

+79
-61
lines changed

3 files changed

+79
-61
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ a set of rules that precisely define a sequence of operations.
128128
* `B` [Square Matrix Rotation](src/algorithms/uncategorized/square-matrix-rotation) - in-place algorithm
129129
* `B` [Jump Game](src/algorithms/uncategorized/jump-game) - backtracking, dynamic programming (top-down + bottom-up) and greedy examples
130130
* `B` [Unique Paths](src/algorithms/uncategorized/unique-paths) - backtracking, dynamic programming and Pascal's Triangle based examples
131+
* `B` [Rain Terraces](src/algorithms/uncategorized/rain-terraces) - trapping rain water problem
131132
* `A` [N-Queens Problem](src/algorithms/uncategorized/n-queens)
132133
* `A` [Knight's Tour](src/algorithms/uncategorized/knight-tour)
133134

‎src/algorithms/uncategorized/rain-terraces/spec/rainTerraces.test.js ‎src/algorithms/uncategorized/rain-terraces/__test__/rainTerraces.test.js

+9
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@ import rainTerraces from '../rainTerraces';
22

33
describe('rainTerraces', () => {
44
it('should find the amount of water collected after raining', () => {
5+
expect(rainTerraces([1])).toBe(0);
6+
expect(rainTerraces([1, 0])).toBe(0);
7+
expect(rainTerraces([0, 1])).toBe(0);
8+
expect(rainTerraces([0, 1, 0])).toBe(0);
9+
expect(rainTerraces([0, 1, 0, 0])).toBe(0);
10+
expect(rainTerraces([0, 1, 0, 0, 1, 0])).toBe(2);
11+
expect(rainTerraces([0, 2, 0, 0, 1, 0])).toBe(2);
512
expect(rainTerraces([2, 0, 2])).toBe(2);
13+
expect(rainTerraces([2, 0, 5])).toBe(2);
614
expect(rainTerraces([3, 0, 0, 2, 0, 4])).toBe(10);
715
expect(rainTerraces([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toBe(6);
816
expect(rainTerraces([1, 1, 1, 1, 1])).toBe(0);
917
expect(rainTerraces([1, 2, 3, 4, 5])).toBe(0);
1018
expect(rainTerraces([4, 1, 3, 1, 2, 1, 2, 1])).toBe(4);
19+
expect(rainTerraces([0, 2, 4, 3, 4, 2, 4, 0, 8, 7, 0])).toBe(7);
1120
});
1221
});

‎src/algorithms/uncategorized/rain-terraces/rainTerraces.js

+69-61
Original file line numberDiff line numberDiff line change
@@ -2,76 +2,84 @@
22
* @param {number[]} terraces
33
* @return {number}
44
*/
5-
6-
/*
7-
* STEPS
8-
* 1. Find the highest terraces on the left and right side of the elevation map:
9-
* e.g. [0, 2, 4, 3, 1, 2, 4, 0, 8, 7, 0] => (leftMax = 4, rightMax = 8)
10-
* This is because water will "trail off" the sides of the terraces.
11-
*
12-
* 2. At this point, we are essentially dealing with a new map: [4, 3, 4, 2, 4, 0, 8].
13-
* From here, we loop through the map from the left to the right (if leftMax > rightMax,
14-
* otherwise we move from right to left), adding water as we go unless we reach a value
15-
* that is greater than or equal to leftMax || rightMax.
16-
* e.g. [4, 3, 4, 2, 4, 0, 8]
17-
* ^
18-
* water += leftMax - 3 => water = 1
19-
* or if the terrace array was reversed:
20-
* e.g. [8, 0, 4, 2, 4, 3, 4]
21-
* ^
22-
* water += rightMax - 3 => water = 1
23-
*
24-
* 3. Again, we've essentially shortened the map: [4, 2, 4, 0, 8].
25-
* Now we repeat the above steps on the new array.
26-
* e.g.
27-
* Next Iteration:
28-
* [4, 2, 4, 0, 8]
29-
* ^
30-
* water += leftMax - 2 => water = 3
31-
*
32-
* Next Iteration:
33-
* [4, 0, 8]
34-
* ^
35-
* water += leftMax - 0 => water = 7
36-
*
37-
* return water(7)
38-
*/
395
export default function rainTerraces(terraces) {
40-
let start = 0;
41-
let end = terraces.length - 1;
42-
let water = 0;
43-
let leftMax = 0;
44-
let rightMax = 0;
6+
/*
7+
* STEPS
8+
*
9+
* 1. Find the highest terraces on the left and right side of the elevation map:
10+
* e.g. for [0, 2, 4, 3, 4, 2, 4, 0, 8, 7, 0] we would have leftMax = 4 and rightMax = 8.
11+
* This is because water will "trail off" the sides of the terraces.
12+
*
13+
* 2. At this point, we are essentially dealing with a new map: [4, 3, 4, 2, 4, 0, 8].
14+
* From here, we loop through the map from the left to the right if leftMax < rightMax
15+
* (otherwise we move from right to left), adding water as we go unless we reach a value
16+
* that is greater than or equal to leftMax or rightMax.
17+
* e.g. [4, 3, 4, 2, 4, 0, 8]
18+
* ^
19+
* water = water + (leftMax - 3) = 1
20+
*
21+
* or if the terrace array was reversed:
22+
* e.g. [8, 0, 4, 2, 4, 3, 4]
23+
* ^
24+
* water = water + (rightMax - 3) = 1
25+
*
26+
* 3. Again, we've essentially shortened the map: [4, 2, 4, 0, 8].
27+
* Now we repeat the above steps on the new array.
28+
*
29+
* Next Iteration:
30+
* [4, 2, 4, 0, 8]
31+
* ^
32+
* water = water + (leftMax - 2) = 3
33+
*
34+
* Next Iteration:
35+
* [4, 0, 8]
36+
* ^
37+
* water = water + (leftMax - 0) = 7
38+
*
39+
* 4. Return result: 7
40+
*/
41+
let leftIndex = 0;
42+
let rightIndex = terraces.length - 1;
43+
44+
let leftMaxLevel = 0;
45+
let rightMaxLevel = 0;
4546

46-
while (start < end) {
47-
// Loop to find left max
48-
while (start < end && terraces[start] <= terraces[start + 1]) {
49-
start += 1;
47+
let waterAmount = 0;
48+
49+
while (leftIndex < rightIndex) {
50+
// Loop to find the highest terrace from the left side.
51+
while (leftIndex < rightIndex && terraces[leftIndex] <= terraces[leftIndex + 1]) {
52+
leftIndex += 1;
5053
}
51-
leftMax = terraces[start];
5254

53-
// Loop to find right max
54-
while (end > start && terraces[end] <= terraces[end - 1]) {
55-
end -= 1;
55+
leftMaxLevel = terraces[leftIndex];
56+
57+
// Loop to find the highest terrace from the right side.
58+
while (rightIndex > leftIndex && terraces[rightIndex] <= terraces[rightIndex - 1]) {
59+
rightIndex -= 1;
5660
}
57-
rightMax = terraces[end];
5861

59-
// Determine which direction we need to move in
60-
if (leftMax < rightMax) {
61-
// Move from left to right and collect water
62-
start += 1;
63-
while (start < end && terraces[start] <= leftMax) {
64-
water += leftMax - terraces[start];
65-
start += 1;
62+
rightMaxLevel = terraces[rightIndex];
63+
64+
// Determine which direction we need to go.
65+
if (leftMaxLevel < rightMaxLevel) {
66+
// Move from left to right and collect water.
67+
leftIndex += 1;
68+
69+
while (leftIndex < rightIndex && terraces[leftIndex] <= leftMaxLevel) {
70+
waterAmount += leftMaxLevel - terraces[leftIndex];
71+
leftIndex += 1;
6672
}
6773
} else {
68-
// Move from left to right and collect water
69-
end -= 1;
70-
while (end > start && terraces[end] <= rightMax) {
71-
water += rightMax - terraces[end];
72-
end -= 1;
74+
// Move from right to left and collect water.
75+
rightIndex -= 1;
76+
77+
while (leftIndex < rightIndex && terraces[rightIndex] <= rightMaxLevel) {
78+
waterAmount += rightMaxLevel - terraces[rightIndex];
79+
rightIndex -= 1;
7380
}
7481
}
7582
}
76-
return water;
83+
84+
return waterAmount;
7785
}

0 commit comments

Comments
 (0)
Please sign in to comment.