$aler = set();
$ingr = set();
foreach ($input->lines as $line) {
[$_, $i, $a] = $line->match("/^(.+) \(contains (.*)\)$/");
$i = explode(" ", $i);
$ingr = $ingr->merge($i);
foreach (explode(", ", $a) as $al) {
$aler[$al] = isset($aler[$al]) ? $aler[$al]->keep($i) : set($i);
}
}
// ==================================================
// > PART 1
// ==================================================
$solution_1 = $ingr->remove($aler->merge()->unique())->count();
// ==================================================
// > PART 2
// ==================================================
while (true) {
foreach ($aler as $i=>$a) {
if (!is_string($a) && $a->count() == 1) {
$aler[$i] = $al = $a->values()[0];
foreach ($aler as $j=>$b) if (!is_string($aler[$j])) $aler[$j] = $aler[$j]->remove([$al]);
continue 2;
}
}
break;
}
$solution_2 = $aler->sortKeys()->join(",");