Skip to content

Instantly share code, notes, and snippets.

@mathiasverraes mathiasverraes/water.php
Last active Jul 19, 2018

Embed
What would you like to do?
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]);
@mathiasverraes

This comment has been minimized.

@Akii

This comment has been minimized.

Copy link

Akii commented Dec 10, 2016

afaik tail([]) should throw an exception

@mathiasverraes

This comment has been minimized.

Copy link
Owner Author

mathiasverraes commented Mar 20, 2018

thanks, fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.