Advent of code 2024/4
Ajax Direct

Answer 59ms

Part 1 : 2536 Part 2 : 1875
$grid = $input->grid();

// ==================================================
// > PART 1
// ==================================================
$solution_1 = 0;
foreach ($grid->searchAll("X") as [$x, $y]) {
    foreach ([-1, 0, 1] as $dx) foreach ([-1, 0, 1] as $dy) {
        if (!$dx && !$dy) continue;
        [$nx, $ny] = [$x, $y];
        for ($i = 0; $i < 3; $i++) {
            [$nx, $ny] = [$nx + $dx, $ny + $dy];
            if ($grid->get([$nx, $ny]) != ["M", "A", "S"][$i]) continue 2;
        }
        $solution_1++;
    }
}

// ==================================================
// > PART 2
// ==================================================
$solution_2 = set($grid->searchAll("A"))->filter(function ($pos) use ($grid) {
    [$x, $y] = [$pos[0], $pos[1]];
    $words = [
        $grid->get([$x - 1, $y - 1]) . "A" . $grid->get([$x + 1, $y + 1]),
        $grid->get([$x + 1, $y - 1]) . "A" . $grid->get([$x - 1, $y + 1])
    ];
    foreach ($words as $word) {
        if ($word != "MAS" && $word != "SAM") return false;
    }
    return true;
})->count();