def core_number(G):
    degrees = dict(G.degree())
    nodes = sorted(degrees, key=degrees.get)
    bin_boundaries = [0]
    curr_degree = 0
    for (i, v) in enumerate(nodes):
        if (degrees[v] > curr_degree):
            bin_boundaries.extend(([i] * (degrees[v] - curr_degree)))
            curr_degree = degrees[v]
    node_pos = {v: pos for (pos, v) in enumerate(nodes)}
    core = degrees
    nbrs = {v: list(nx.all_neighbors(G, v)) for v in G}
    for v in nodes:
        for u in nbrs[v]:
            if (core[u] > core[v]):
                nbrs[u].remove(v)
                pos = node_pos[u]
                bin_start = bin_boundaries[core[u]]
                node_pos[u] = bin_start
                node_pos[nodes[bin_start]] = pos
                (nodes[bin_start], nodes[pos]) = (nodes[pos], nodes[bin_start])
                bin_boundaries[core[u]] += 1
                core[u] -= 1
    return core
def core_number(G):
    degrees = dict(G.degree())
    nodes = sorted(degrees, key=degrees.get)
    bin_boundaries = [0]
    curr_degree = 0
    for (i, v) in enumerate(nodes):
        if (degrees[v] > curr_degree):
            bin_boundaries.extend(([i] * (degrees[v] - curr_degree)))
            curr_degree = degrees[v]
    node_pos = {v: pos for (pos, v) in enumerate(nodes)}
    core = degrees
    nbrs = {v: list(nx.all_neighbors(G, v)) for v in G}
    for v in nodes:
        for u in nbrs[v]:
            if (core[u] > core[v]):
                nbrs[u].remove(v)
                pos = node_pos[u]
                bin_start = bin_boundaries[core[u]]
                node_pos[u] = bin_start
                node_pos[nodes[bin_start]] = pos
                (nodes[bin_start], nodes[pos]) = (nodes[pos], nodes[bin_start])
                bin_boundaries[core[u]] += 1
                core[u] -= 1
    return core