$a = $input->numbers->sort()->values();
$a->insert(0, 0)->insert($goal = $a->max() + 3);
// ==================================================
// > PART 1
// ==================================================
$diffs = [1 => 0, 3 => 0];
for ($i = 0; $i < $a->count() - 1; $i++) {
$diffs[$a[$i+1] - $a[$i]]++;
}
$solution_1 = $diffs[1] * $diffs[3];
// ==================================================
// > PART 2
// ==================================================
function arrangements_from($from, $a, &$memory)
{
if (isset($memory[$from])) return $memory[$from];
$total = 0;
foreach ($a->keep(range($from + 1, $from + 3)) as $n)
$total += arrangements_from($n, $a, $memory);
$memory[$from] = $total;
return $total;
}
$memory = [$goal => 1];
$solution_2 = arrangements_from(0, $a, $memory);