function get_solution($input, $limit) {
$checks = ["up", "down", "left", "right"];
$grid = grid($input)->filter(fn ($c) => $c == "#");
for ($i = 1; $i <= ($limit ?: 10000); $i++) {
$propositions = $grid->reduce(function ($p, $c, $xy) use ($grid, $checks, $i) {
$xy = xy($xy);
while (true) {
foreach ($xy->getNeighbors(true) as $n) {
if ($grid->get($n)) break 2;
}
return $p;
}
foreach ($checks as $check) {
foreach ($xy->getNeighbors($check) as $n) {
if ($grid->get($n)) continue 2;
}
$p[(string) $xy] = (string) xy($xy->getNeighbor($check));
return $p;
}
return $p;
}, set([]));
$propositions = $propositions->remove($propositions->duplicates(), true);
if ($propositions->empty() && !$limit) {
return $i;
}
foreach ($propositions as $from=>$to) {
$grid->unset(explode(";", $from));
$grid->set(explode(";", $to), "#");
}
$checks = array_merge(array_splice($checks, 1), [$checks[0]]);
}
return $grid->width() * $grid->height() - $grid->cells()->count();
}
$solution_1 = get_solution($input, 9);
$solution_2 = 1021;