JSFiddle - React, Tailwind, and code Playground
by moeishaa
JavaScript
// min number of depths to form a valley, start peak + dip + end peak
const minStreak = 3;
/**
* Checks if a streak is valid
* A streak is valid if all dips are lower (or equal) than start and end peak
* @param {number[]} streak Current streak
* @return {boolean} True if streak is valid, false otherwise
*/
const isValid = streak => {
let clone = [...streak],
startPeak = clone.shift(),
endPeak = clone.pop();
return clone.every(n => n <= startPeak && n <= endPeak);
};
/**
* Calculate flood volume
* @param {number[]} streak Possible streak/valley to check volume of
* @return {number} Calculated flood volume of provided streak
*/
const calcFlood = streak => {
if (streak.length < minStreak || !isValid(streak)) return 0;
// sort the list and dump the maximum peak, water can only rise to second highest peak
streak = streak.sort().slice(0, -1);
// pick where the water can rise upto
let max = streak.pop();
return streak.reduce((sum, current) => sum + max - current, 0);
};
/**
* Main method to solve the problem
* @param {number[]} valley Initial valley structure
* @return {number} Calculate flood volume of entire valley
*/
const solve = valley => {
let vol = 0,
// initially streak is just the first element
streak = [valley.shift()],
// peak is also blindly set to first element
peak = streak[0];
while (valley.length) {
if (valley[0] < peak) {
// streak continues since the element is less than the last observed peak
streak.push(valley.shift());
}
else {
// streak has been broken, a possible valley is formed
streak.push(valley[0]);
vol += calcFlood(streak);
// reset streak and peak to be the current element
streak = [valley.shift()];
peak = streak[0];
}
}
// check for possible tail valley
vol += calcFlood(streak);
return vol;
};
console.log(solve([2, 4, 5, 2, 3, 4, 6, 6, 4, 5])); // 7
console.log(solve([3, 2, 1, 2])); //...