Answer ⏱ 7ms
Part 1 :
531932
Part 2 :
73646890
// ==================================================
// > PARSE : Find the positions of all symbols, digits and numbers
// ==================================================
$symbols = $digits = $numbers = [];
foreach ($input->lines as $y=>$line) {
foreach (str_split($input->lines[$y]) as $x=>$c) {
if ($c == ".") continue;
if (!is_numeric($c)) {
$symbols[$y][$x] = $c;
continue;
}
if ($x && is_numeric($line[$x - 1])) {
$digits[count($digits) - 1] .= $c;
} else {
$digits[] = $c;
}
$numbers[$y][$x] = count($digits) - 1;
}
}
// ==================================================
// > SOLVE
// ==================================================
$solution_1 = $solution_2 = 0;
foreach ($symbols as $y=>$row) {
foreach ($row as $x=>$s) {
$neighbors = set();
foreach (neighbors([$x, $y], true) as [$nx, $ny]) {
if (isset($numbers[$ny][$nx])) $neighbors[] = $numbers[$ny][$nx];
}
$neighbors = $neighbors->unique()->map(fn ($i) => $digits[$i]);
$solution_1 += $neighbors->sum();
if ($s == "*" && $neighbors->count() == 2) $solution_2 += $neighbors->multiply();
}
}