def separate_groups(groups, key, total):
    optimum, extra = compute_optimum(len(groups), total)
    over_loaded, under_loaded, optimal = _smart_separate_groups(groups, key, total)
    if not extra:
        return over_loaded, under_loaded
    potential_under_loaded = [
        group for group in optimal
        if key(group) == optimum
    ]
    potential_over_loaded = [
        group for group in optimal
        if key(group) > optimum
    ]
    revised_under_loaded = under_loaded + potential_under_loaded
    revised_over_loaded = over_loaded + potential_over_loaded
    return (
        sorted(revised_over_loaded, key=key, reverse=True),
        sorted(revised_under_loaded, key=key),
    )