/**
* Check if an item is close enough from a group to join it
*/
function is_close_enough($group, $a) {
foreach ($group as $b) {
$manhattan = abs($a[0] - $b[0]) + abs($a[1] - $b[1]) + abs($a[2] - $b[2]) + abs($a[3] - $b[3]);
if ($manhattan <= 3) return true;
}
return false;
}
/**
* If an item can merge one or more groups, merge all of them together.
* Else create a new group.
*/
$items = (array) $input->lines->map(fn ($l) => explode(",", $l));
$groups = [];
foreach ($items as $item) {
$can_merge = [];
$new_group = [$item];
foreach ($groups as $g=>$group) {
if (is_close_enough($group, $item)) {
$can_merge[] = $g;
}
}
if (!empty($can_merge)) {
foreach ($can_merge as $c) {
$new_group = array_merge($new_group, $groups[$c]);
unset($groups[$c]);
}
}
$groups[] = $new_group;
}
$solution_1 = count($groups);
$solution_2 = "⭐";