Skip to content

Instantly share code, notes, and snippets.

@mathiasverraes
Last active July 19, 2018 05:23
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mathiasverraes/cb9917c205782621332893a5c3dc7e70 to your computer and use it in GitHub Desktop.
Save mathiasverraes/cb9917c205782621332893a5c3dc7e70 to your computer and use it in GitHub Desktop.
Water Kata
<?php declare(strict_types = 1);
function volume (array $levels) {
return array_sum(
zipWith(
'subtract',
zipWith(
'min',
scanl('max', $levels),
scanr('max', $levels)
),
$levels
)
);
}
// tests
assert(volume([1, 5, 3, 7, 2]) == 2);
assert(volume([5, 3, 7, 2, 6, 4, 5, 9, 1, 2] ) === 14);
assert(volume([2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1] ) === 35);
assert(volume([5, 5, 5, 5]) === 0);
assert(volume([5, 6, 7, 8]) === 0);
assert(volume([8, 7, 7, 6]) === 0);
assert(volume([6, 7, 10, 7, 6]) === 0);
// missing functions in php core
function subtract($x, $y) { return $x - $y; }
function scanl(callable $f, array $l) : array {
$f2 = function($carry, $item) use ($f) {
return array_merge($carry, [$f(last($carry, $item), $item)]);
};
return array_reduce($l, $f2, []);
}
function scanr(callable $f, array $l) : array {
return array_reverse(scanl($f, array_reverse($l)));
}
function head(array $l) {
if(count($l)) return $l[0];
throw new InvalidArgumentException("Empty list");
}
function tail(array $l) {
if(count($l)) return array_slice($l, 1);
throw new InvalidArgumentException("Empty list");
}
function last(array $l, $default) {
return
count($l)
? array_slice($l, -1)[0]
: $default;
}
function zipWith(callable $f, array $left, array $right) : array {
return
empty($left) || empty($right)
? []
: array_merge(
[$f(head($left), head($right))],
zipWith($f, tail($left), tail($right))
);
}
assert(head([1, 5, 3, 7, 2]) === 1);
assert(tail([1, 5, 3, 7, 2]) === [5, 3, 7, 2]);
assert(tail([1]) === []);
assert(last([], 3) === 3);
assert(last([1, 5, 3, 7, 2], 3) === 2);
assert(zipWith('max', [1,2,3], [3,2,1]) === [3,2,3]);
assert(scanl('max', [1, 5, 3, 7, 2]) === [1, 5, 5, 7, 7]);
assert(scanr('max', [1, 5, 3, 7, 2]) === [7, 7, 7, 7, 2]);
@Akii
Copy link

Akii commented Dec 10, 2016

afaik tail([]) should throw an exception

@mathiasverraes
Copy link
Author

thanks, fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment