$grid = grid();
$couples = [];
// Draw sources and beacons
foreach ($input->lines as $line) {
preg_match_all('/[-0-9]+/', $line, $matches);
$couple = [xy([$matches[0][0], $matches[0][1]]), xy([$matches[0][2], $matches[0][3]])];
$couples[] = $couple;
$grid->set($couple[0], "S");
$grid->set($couple[1], "B");
}
// ==================================================
// > PART 1
// ==================================================
$search = 2000000;
$ranges = [];
foreach ($couples as $couple) {
$radius = $couple[0]->manhattan($couple[1]);
// If the beacon is too far, skip
if ($couple[0][1] - $radius > $search || $couple[0][1] + $radius < $search) continue;
// Get the x range at the search level
$ranges[] = [$couple[0][0] - ($radius - abs($couple[0][1] - $search)), $couple[0][0] + ($radius - abs($couple[0][1] - $search))];
}
// Count the number of points in the merged ranges
$count = set($ranges)->mergeRanges()
->reduce(fn ($count, $range) => $count + $range[1] - $range[0] + 1, 0);
// All the coverd points minus the beacons
$solution_1 = $count - $grid[2000000]->keep("B")->count();
// ==================================================
// > PART 2
// ==================================================
$intersections = set();
// Find interections that are just outside of the known areas
for ($i = 0; $i < count($couples); $i++) {
$area = new GridCircle($couples[$i][0], $couples[$i][0]->manhattan($couples[$i][1]) + 1);
for ($j = $i + 1; $j < count($couples); $j++) {
$intersections = $intersections->merge($area->getIntersections(
new GridCircle($couples[$j][0], $couples[$j][0]->manhattan($couples[$j][1]) + 1)
));
}
}
// Keep only the ones between 0 and 4000000
$intersections = $intersections->filter(fn ($xy) => $xy[0] >= 0 && $xy[1] >= 0 && $xy[0] <= 4000000 && $xy[1] <= 4000000);
foreach ($intersections as $intersection) {
foreach ($couples as $couple) {
$radius = $couple[0]->manhattan($couple[1]);
$distance = $couple[0]->manhattan($intersection);
if ($distance <= $radius) continue 2;
}
break;
}
$xy = xy($intersection);
$solution_2 = $xy[0] * 4000000 + $xy[1];