Advent of code 2015/18
Ajax Direct

Answer

Part 1 :
Part 2 :
function turn_corners_on($grid) {
    $grid[0][0] = "#";
    $grid[0][99] = "#";
    $grid[99][0] = "#";
    $grid[99][99] = "#";
    return $grid;
}

function get_neighbors_on($x, $y, $grid)
{
    $count = 0;
    for ($nx = $x - 1; $nx <= $x + 1; $nx++) {
        for ($ny = $y - 1; $ny <= $y + 1; $ny++) {
            if ($nx == $x && $ny == $y) continue;
            $count += ($grid[$ny][$nx] ?? null) == "#" ? 1 : 0;
        }
    }
    return $count;
}

function toggle($lights, $stuck_corners = false) {
    $next = [];

    if ($stuck_corners) $lights = turn_corners_on($lights);

    foreach ($lights as $y=>$row) {
        foreach ($row as $x=>$light) {
            $on = get_neighbors_on($x, $y, $lights);

            if ($light == "#") {
                $next[$y][$x] = ($on != 2 && $on != 3) ? "." : "#";
            }
            else {
                $next[$y][$x] = $on != 3 ? "." : "#";
            }
        }
    }

    if ($stuck_corners) $next = turn_corners_on($next);

    return $next;
}

// ==================================================
// > SOLUTIONS
// ==================================================
$lights = (array) grid($input)->rows()->map(fn ($row) => (array) $row);
for ($i = 0; $i < 100; $i++) $lights = toggle($lights);
$solution_1 = grid($lights)->cells()->keep("#")->count();

$lights = (array) grid($input)->rows()->map(fn ($row) => (array) $row);
for ($i = 0; $i < 100; $i++) $lights = toggle($lights, true);
$solution_2 = grid($lights)->cells()->keep("#")->count();