Make Rain Terraces more terse using standard array functions

This commit is contained in:
Bruce Feldman 2018-08-10 13:26:37 -04:00
parent 70ec623cbf
commit 680ee713a6

View File

@ -5,43 +5,11 @@
* @return {number}
*/
export default function dpRainTerraces(terraces) {
let waterAmount = 0;
// Obtain the maximum elevations to the left and right of each terrace (inclusive).
const maxL = terraces.reduce((acc, val, idx) => [...acc, Math.max(val, (acc[idx - 1] || 0))], []);
const maxR = terraces.reduceRight((acc, val) => [Math.max(val, (acc[0] || 0)), ...acc], []);
// Init arrays that will keep the list of left and right maximum levels for specific positions.
const leftMaxLevels = new Array(terraces.length).fill(0);
const rightMaxLevels = new Array(terraces.length).fill(0);
// Calculate the highest terrace level from the LEFT relative to the current terrace.
[leftMaxLevels[0]] = terraces;
for (let terraceIndex = 1; terraceIndex < terraces.length; terraceIndex += 1) {
leftMaxLevels[terraceIndex] = Math.max(
terraces[terraceIndex],
leftMaxLevels[terraceIndex - 1],
);
}
// Calculate the highest terrace level from the RIGHT relative to the current terrace.
rightMaxLevels[terraces.length - 1] = terraces[terraces.length - 1];
for (let terraceIndex = terraces.length - 2; terraceIndex >= 0; terraceIndex -= 1) {
rightMaxLevels[terraceIndex] = Math.max(
terraces[terraceIndex],
rightMaxLevels[terraceIndex + 1],
);
}
// Not let's go through all terraces one by one and calculate how much water
// each terrace may accumulate based on previously calculated values.
for (let terraceIndex = 0; terraceIndex < terraces.length; terraceIndex += 1) {
// Pick the lowest from the left/right highest terraces.
const currentTerraceBoundary = Math.min(
leftMaxLevels[terraceIndex],
rightMaxLevels[terraceIndex],
);
if (currentTerraceBoundary > terraces[terraceIndex]) {
waterAmount += currentTerraceBoundary - terraces[terraceIndex];
}
}
return waterAmount;
// Convert maximum values to amount of water at current index and sum water values.
const trap = terraces.map((val, idx) => Math.max(0, Math.min(maxL[idx], maxR[idx]) - val));
return trap.reduce((acc, val) => acc + val);
}