Advent of code 2018/13
Ajax Direct

Answer

Part 1 :
Part 2 :
$grid  = (array) $input->lines->map(fn ($l) => str_split($l));
$carts = [];
$crash = [];
$dirs  = "^>v<";

// Scan grid for carts
for ($x = 0; $x < count($grid[0]); $x++) {
    for ($y = 0; $y < count($grid); $y++) {
        if (($dir = strpos($dirs, $grid[$y][$x])) !== false) {
            $carts[]      = [$x, $y, $dir, 0];
            $grid[$y][$x] = $dir == 0 || $dir == 2 ? "|" : "-";
        }
    }
}

while (count($crash) < count($carts) - 1) {

    // Move carts in order : top-left to bottom-right
    $order = array_keys($carts);
    usort($order, function ($a, $b) use ($carts) {
        if ($carts[$a][1] == $carts[$b][1]) return $carts[$a][0] <=> $carts[$b][0];
        return $carts[$a][1] <=> $carts[$b][1];
    });

    foreach ($order as $i) {
        $cart = $carts[$i];

        // Skip crashed carts
        if (!empty($crash[$i])) continue;

        // Move
        match ($cart[2]) {
            0 => $cart[1]--,
            1 => $cart[0]++,
            2 => $cart[1]++,
            3 => $cart[0]--,
        };

        // Rotate at intersections
        $cart[2] = match ($grid[$cart[1]][$cart[0]]) {
            "+" => match ($cart[3]++ % 3) {
                0 => ($cart[2] + 3) % 4,
                1 => $cart[2],
                2 => ($cart[2] + 1) % 4,
            },
            "/" =>  $cart[2] = [1, 0, 3, 2][$cart[2]],
            "\\" => $cart[2] = [3, 2, 1, 0][$cart[2]],
            "|", "-" => $cart[2]
        };
        $carts[$i] = $cart;

        // Check for collision
        foreach ($carts as $j=>$other) {
            if (empty($crash[$j]) && $i != $j && $other[0] == $cart[0] && $other[1] == $cart[1]) {
                $crash[$i] = true;
                $crash[$j] = true;
            }
        }
    }
}

// ==================================================
// > PART 1
// ==================================================
$first_crash = $carts[array_keys($crash)[0]];
$solution_1 = $first_crash[0] . "," . $first_crash[1];

// ==================================================
// > PART 2
// ==================================================
$cart_left = array_values(array_diff_key($carts, $crash))[0];
$solution_2 = $cart_left[0] . "," . $cart_left[1];