Water collected between towers: Difference between revisions
→JS :: ES6: Tidied, updated primitives.
(Added Tailspin solution) |
(→JS :: ES6: Tidied, updated primitives.) |
||
Line 1,289:
<lang JavaScript>(() => {
'use strict';
// ---------- WATER COLLECTED BETWEEN TOWERS -----------
// waterCollected :: [Int] -> Int
const waterCollected = xs =>
)
//
const main = () => [
[1, 5, 3, 7, 2],
[5, 3, 7, 2, 6, 4, 5, 9, 1, 2],
[2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],
[5, 5, 5, 5],
[5, 6, 7, 8],
[8, 7, 7, 6],
[6, 7, 10, 7, 6]
].map(waterCollected);
// ---------------------- GENERIC ----------------------
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
// filter :: (a -> Bool) -> [a] -> [a]
const filter = p =>
// The elements of xs which match
// the predicate p.
xs => [...xs].filter(p);
// gt :: Ord a => a -> a -> Bool
const gt = x => y =>
'Tuple' === x.type ? (
x[0] > y[0]
) : (x > y);
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
'GeneratorFunction' !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
// lt (<) :: Ord a => a -> a -> Bool
const lt = a =>
b => a < b;
// max :: Ord a => a -> a -> a
const max =
// b if its greater than a,
// otherwise a.
b => a > b ? a : b;
// min :: Ord a => a -> a -> a
const min =
b => b < a ? b : a;
// scanl :: (b -> a -> b) -> b -> [a] -> [b]
const scanl =
}, Tuple(startValue)([startValue]))[1];
// scanl1 :: (a -> a -> a) -> [a] -> [a]
const scanl1 =
// starting value argument.
xs => xs.length > 0 ? (
scanl(f)(
xs[0]
)(xs.slice(1))
) : [];
// scanr :: (b -> a -> b) -> b -> [a] -> [b]
const scanr =
}, Tuple(startValue)([startValue]))[1];
// scanr1 :: (a -> a -> a) -> [a] -> [a]
const scanr1 =
// seed-value argument, and assumes that
// xs is not empty.
xs => xs.length > 0 ? (
scanr(f)(
xs.slice(-1)[0]
)(xs.slice(0, -1))
) : [];
//
const
//
const sum = xs =>
// The numeric sum of all values in xs.
xs.reduce((a, x) => a + x, 0);
// take :: Int -> [a] -> [a]
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => xs.slice(0, n);
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
// A list constructed by zipping with a
// custom function, rather than with the
// default tuple constructor.
xs => ys => ((xs_, ys_) => {
const lng = Math.min(length(xs_), length(ys_));
return take(lng)(xs_).map(
(x, i) => f(x)(ys_[i])
);
})(xs, ys);
// MAIN ---
return main();
})();</lang>
{{Out}}
|