Advent of code 2020/7
Ajax Direct

Answer

Part 1 :
Part 2 :
// ==================================================
// > PART 1
// ==================================================
$parents = $input->lines->reduce(function ($parents, $line) {
    $bags = $line->matchAll("/([a-z]+ [a-z]+) bags?/")[1];
    foreach (array_slice($bags, 1) as $child) {
        $parents[$child][] = $bags[0];
    }
    return $parents;
}, []);

function add_parents($list, $item, $parents) {
    $list = array_merge($list, $parents[$item] ?? []);
    foreach ($parents[$item] ?? [] as $parent) {
        $list = add_parents($list, $parent, $parents);
    }
    return $list;
}

$solution_1 = count(array_unique(add_parents([], "shiny gold", $parents)));


// ==================================================
// > PART 2
// ==================================================
$children = $input->lines->reduce(function ($children, $line) {
    $bags = $line->matchAll("/([a-z]+ [a-z]+) bags?/")[1];
    $counts = $line->numbers();
    if ($counts->empty()) return $children;
    $children[$bags[0]] = array_combine(array_slice($bags, 1), (array) $counts);
    return $children;
}, []);

function add_children_count($count, $item, $mult, $children)
{
    $count += array_sum($children[$item] ?? []) * $mult;
    foreach ($children[$item] ?? [] as $child=>$m) {
        $count = add_children_count($count, $child, $m * $mult, $children);
    }
    return $count;
}

$solution_2 = add_children_count(0, "shiny gold", 1, $children);