Answer ⏱ 966ms
Part 1 :
441
Part 2 :
⭐
$grid = (new Grid($input));
[$w, $h] = [$grid->width(), $grid->height()];
$pos = (array) $grid->filter(fn ($c) => $c != ".")->reduce(function ($carry, $c, $xy) {
$carry[(int) ($c == "v")][$xy[0]][$xy[1]] = true;
return $carry;
}, set([]))->sortKeys();
$solution_1 = 0;
while (true) {
$solution_1++;
$moved = false;
foreach ($pos as $d=>$p) {
$npos = [];
foreach ($p as $x=>$px) foreach ($px as $y=>$py) {
[$nx, $ny] = [$x, $y];
if ($d) // Down
$ny = ($y+1)%$h;
else // Left
$nx = ($x+1)%$w;
if (!isset($pos[0][$nx][$ny]) && !isset($pos[1][$nx][$ny])) {
$npos[$d][$nx][$ny] = true;
$moved = true;
} else {
$npos[$d][$x][$y] = true;
}
}
$pos[$d] = $npos[$d];
}
if (!$moved) break;
}
$solution_2 = "⭐";