Task: Topological sort_Extracted top item





Java: import java.util.*;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

public class TopologicalSort2 {

    public static void main(String[] args) {
        String s = "top1,top2,ip1,ip2,ip3,ip1a,ip2a,ip2b,ip2c,ipcommon,des1,"
                + "des1a,des1b,des1c,des1a1,des1a2,des1c1,extra1";

        Graph g = new Graph(s, new int[][]{
            {0, 10}, {0, 2}, {0, 3},
            {1, 10}, {1, 3}, {1, 4},
            {2, 17}, {2, 5}, {2, 9},
            {3, 6}, {3, 7}, {3, 8}, {3, 9},
            {10, 11}, {10, 12}, {10, 13},
            {11, 14}, {11, 15},
            {13, 16}, {13, 17},});

        System.out.println("Top levels: " + g.toplevels());
        String[] files = {"top1", "top2", "ip1"};
        for (String f : files)
            System.out.printf("Compile order for %s %s%n", f, g.compileOrder(f));
    }
}

class Graph {
    List<String> vertices;
    boolean[][] adjacency;
    int numVertices;

    public Graph(String s, int[][] edges) {
        vertices = asList(s.split(","));
        numVertices = vertices.size();
        adjacency = new boolean[numVertices][numVertices];

        for (int[] edge : edges)
            adjacency[edge[0]][edge[1]] = true;
    }

    List<String> toplevels() {
        List<String> result = new ArrayList<>();
        
        outer:
        for (int c = 0; c < numVertices; c++) {
            for (int r = 0; r < numVertices; r++) {
                if (adjacency[r][c])
                    continue outer;
            }
            result.add(vertices.get(c));
        }
        return result;
    }

    List<String> compileOrder(String item) {
        LinkedList<String> result = new LinkedList<>();
        LinkedList<Integer> queue = new LinkedList<>();

        queue.add(vertices.indexOf(item));

        while (!queue.isEmpty()) {
            int r = queue.poll();
            for (int c = 0; c < numVertices; c++) {
                if (adjacency[r][c] && !queue.contains(c)) {
                    queue.add(c);
                }
            }
            result.addFirst(vertices.get(r));
        }
        return result.stream().distinct().collect(toList());
    }
}



Python: try:
    from functools import reduce
except: pass


def topx(data, tops=None):
    'Extract the set of top-level(s) in topological order'
    for k, v in data.items():
        v.discard(k) 
    if tops is None:
        tops = toplevels(data)
    return _topx(data, tops, [], set())

def _topx(data, tops, _sofar, _sofar_set):
    'Recursive topological extractor'
    _sofar += [tops] 
    _sofar_set.union(tops)
    depends = reduce(set.union, (data.get(top, set()) for top in tops))
    if depends:
        _topx(data, depends, _sofar, _sofar_set)
    ordered, accum = [], set()
    for s in _sofar[::-1]:
        ordered += [sorted(s - accum)]
        accum |= s
    return ordered

def printorder(order):
    'Prettyprint topological ordering'
    if order:
        print("First: " + ', '.join(str(s) for s in order[0]))
    for o in order[1:]:
        print(" Then: " + ', '.join(str(s) for s in o))

def toplevels(data):
    
    for k, v in data.items():
        v.discard(k) 
    dependents = reduce(set.union, data.values())
    return  set(data.keys()) - dependents

if __name__ == '__main__':
    data = dict(
        top1  = set('ip1 des1 ip2'.split()),
        top2  = set('ip2 des1 ip3'.split()),
        des1  = set('des1a des1b des1c'.split()),
        des1a = set('des1a1 des1a2'.split()),
        des1c = set('des1c1 extra1'.split()),
        ip2   = set('ip2a ip2b ip2c ipcommon'.split()),
        ip1   = set('ip1a ipcommon extra1'.split()),
        )

    tops = toplevels(data)
    print("The top levels of the dependency graph are: " + ' '.join(tops))

    for t in sorted(tops):
        print("\nThe compile order for top level: %s is..." % t)
        printorder(topx(data, set([t])))
    if len(tops) > 1:
        print("\nThe compile order for top levels: %s is..."
              % ' and '.join(str(s) for s in sorted(tops)) )
        printorder(topx(data, tops))