def part2(text): def scale(parent): weights[parent] += sum(map(scale, graph[parent])) return weights[parent] def deepflatten(node): yield node yield from chain(*map(deepflatten, graph[node])) r = re.compile(r"([a-z]+) \((\d+)\)(?: -> (.*))?") weights = {} graph = {} for line in text.splitlines(): parent, weight, kids = r.match(line).groups() graph[parent] = empty if kids is None else kids.split(", ") weights[parent] = int(weight) scale(head := unique(chain.from_iterable(map(deepflatten, graph)))) sibs = kids = dict((kid, weights[kid]) for kid in graph[head]) while not all_equal(kids.values()): odd = unique(kids.values()) head = next(kid for kid, weight in kids.items() if weight == odd) sibs, kids = kids, dict((kid, weights[kid]) for kid in graph[head]) return mode(sibs.values()) - len(kids) * next(iter(kids.values()))
def test_all_equal_failure4(): # Changing next method with pytest.raises(_hf.CacheNext.EXC_TYP, match=_hf.CacheNext.EXC_MSG): all_equal(_hf.CacheNext(1))
def test_all_equal_failure2(): # comparison fail with pytest.raises(TypeError): all_equal([T(1), T('a')])
def test_all_equal_failure3(): # Test that a failing iterator doesn't raise a SystemError with pytest.raises(_hf.FailNext.EXC_TYP, match=_hf.FailNext.EXC_MSG): all_equal(_hf.FailNext())
def test_all_equal_failure1(): with pytest.raises(_hf.FailIter.EXC_TYP, match=_hf.FailIter.EXC_MSG): all_equal(_hf.FailIter())
def test_all_equal_normal3(): # generator assert all_equal(i for i in [T(1), T(1), T(1)])
def test_all_equal_normal2(): assert not all_equal([T(1), T(1), T(2)])
def test_all_equal_normal1(): assert all_equal([T(1), T(1), T(1)])
def test_all_equal_empty1(): assert all_equal([])