Advent of code 2023/21
Ajax Direct

Answer

Part 1 :
Part 2 :
$grid = (array) $input->lines->map("str_split");
[$w, $h] = [count($grid[0]), count($grid)];

$s = $input->replace("\n", "")->search("S");
[$xs, $ys] = [$s % $w, intdiv($s, $w)];

$max = ($xs + 2 * $w) + 1;

$graph = new Graph(function ($graph) use ($grid, $max, $w, $h) {
    [$x, $y, $steps] = explode(";", $graph->current);
    $graph->steps[$steps % 2 ? "odd" : "even"]["$x;$y"] = true;

    if (($graph->exploring??null) != $steps) {
        $graph->exploring = $steps;
        if ($steps != $max) {
            $prev = $steps + 1;
            $graph->counts[($max - $prev)] = count($graph->steps[$prev % 2 ? "odd" : "even"]??[]);
        }
    }

    if (--$steps < 0) return [];
    $next = [];
    foreach (neighbors([$x, $y]) as $n) {
        if ($grid[Math::mod($n[1], $h)][Math::mod($n[0], $w)] == "#") continue;

        $n = implode(";", $n);
        if (isset($graph->steps["even"][$n]) || isset($graph->steps["odd"][$n])) continue;

        $next[$n . ";$steps"] = 1;
    }
    return $next;
});

$graph->explore("$xs;$ys;$max");

// ==================================================
// > PART 1
// ==================================================
$solution_1 = $graph->counts[64];

// ==================================================
// > PART 2 : Quadratic polynomial
// ==================================================
[$f0, $f1, $f2] = [$graph->counts[$xs], $graph->counts[$xs + $w], $graph->counts[$xs + 2 * $w]];
$a = ($f2 - 2*$f1 + $f0) / 2;
$b = $f1 - $f0 - $a;
$c = $f0;

$f = fn ($n) => $a*$n**2 + $b*$n + $c;
$n = (26501365 - $xs) / $w;
$solution_2 = $f($n);