Advent of code 2023/6
Ajax Direct

Answer

Part 1 :
Part 2 :
// See utils/shortcuts.php for binary_search()
function find_bound($start, $end, $time, $distance, $dir = 1) {
    return binary_search($start, $end, function ($b, $lb, $ub) use ($time, $distance, $dir) {
        if (abs($lb - $ub) <= 1) return 0;
        return ($distance <=> (($time - $b) * $b)) * $dir;
    });
}

function wins($time, $distance) {
    $lb = find_bound(0, ($time / 2), $time, $distance);
    $ub = find_bound(($time / 2), $time - 1, $time, $distance, -1);
    return $ub - $lb;
}

$races = $input->lines->map(fn ($l) => $l->numbers);

// ==================================================
// > PART 1
// ==================================================
$wins = set();
foreach ($races[0] as $i=>$time) {
    $wins[] = wins($time, $races[1][$i]);
}

$solution_1 = $wins->multiply();

// ==================================================
// > PART 2
// ==================================================
$solution_2 = wins(
    int($races[0]->join()),
    int($races[1]->join()),
);