Advent of code 2024/6
Ajax Direct

Answer

Part 1 :
Part 2 :
function solve($grid, $guard, $dir, $history = [], $reccord_to_try = false) {
    $dirs = [[0, -1], [1, 0], [0, 1], [-1, 0]];
    $pos = [join(";", $guard)];
    $to_try = [];

    while (true) {
        $next = [
            $guard[0] + $dirs[$dir][0],
            $guard[1] + $dirs[$dir][1]
        ];

        switch ($grid->get($next)) {
            case null:
                return [false, array_unique($pos), $to_try];
            case "#":
                $dir = ($dir + 1) % 4;
                break;
            default:
                if ($reccord_to_try) {
                    $to_try[] = [$guard, $next, $dir, $history];
                }

                $guard = $next;
                $pos[] = join(";", $guard);

                $state = join(";", $guard) . ";" . $dir;
                if (isset($history[$state])) {
                    return [true, array_unique($pos)];
                }
                $history[$state] = true;
        }
    }
}

// ==================================================
// > PART 1
// ==================================================
$grid  = $input->grid;
$guard = $grid->search("^");
[$looped, $pos, $to_try] = solve($grid, $guard, 0, [join(";", $guard).";0" => true], true);
$solution_1 = count($pos);

// ==================================================
// > PART 2
// ==================================================
$tries = [];
foreach ($to_try as $try) {
    [$guard, $next, $dir, $history] = $try;
    $ngrid = $grid->set($next, "#");

    $b = join(";", $next);
    if (!isset($tries[$b])) {
        [$tries[$b], $_] = solve($ngrid, $guard, $dir, $history);
    }

    $grid->set($next, ".");
}
$solution_2 = count(array_filter($tries));