$grid = grid($input);
// ==================================================
// > PART 1
// ==================================================
$lowpoints = $grid->map(function ($val, $xy) use ($grid) {
if (int($grid->getNeighbors($xy)->remove([null])->min()) > int($val)) {
return int($val) + 1;
}
return 0;
})->cells();
$solution_1 = $lowpoints->sum();
// ==================================================
// > PART 2
// ==================================================
$basins = $lowpoints->filter()->keys()->map(function ($lp) use ($grid) {
$queue = [$lp];
$seen = [];
while ($queue) {
$visit = array_shift($queue);
$seen[] = $visit;
$queue = array_merge($queue, (array) $grid->getNeighbors(explode(";", $visit))
->remove([null, 9], true)->keys()
->remove($seen)->remove($queue));
}
return count($seen);
});
$solution_2 = $basins->sort()->reverse()->slice(0, 3)->multiply();