// 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()),
);