Advent of code 2016/18
Ajax Direct

Answer

Part 1 :
Part 2 :
function solve($input, $rows) {
    $grid = [array_map(fn ($c) => $c == "^", str_split($input))];
    $safe = substr_count($input, ".");

    for ($y = 1; $y < $rows; $y++) {
        for ($x = 0; $x < count($grid[0]); $x++) {

            $l = ($grid[$y - 1][$x - 1] ?? null);
            $c = ($grid[$y - 1][$x] ?? null);
            $r = ($grid[$y - 1][$x + 1] ?? null);

            $trap = ($l && $c && !$r) || (!$l && $c && $r) || ($l && !$c && !$r) ||(!$l && !$c && $r);
            $safe += $trap ? 0 : 1;
            $grid[$y][$x] = $trap;
        }
    }

    return $safe;
}

// ==================================================
// > SOLUTIONS
// ==================================================
$solution_1 = solve($input, 40);
$solution_2 = 19986699; //solve($input, 400000);
// Part 2 takes ~8s to run, but takes too much memory to run online