Rebol3 Code Examplex


Topological sort

Rebol [
    title: "Rosetta code: Topological sort"
    file:  %Topological_sort.r3
    url:   https://rosettacode.org/wiki/Topological_sort
]

toposort: function [
    "Topologically sort a dependency map, returning a block of blocks (one per level)"
    data [map!]
][
    data: copy/deep data ;; work on a copy so caller's map is untouched

    ;; discard self dependencies
    foreach [k v] data [ if pos: find v k [remove pos] ]

    ;; add any items only ever seen as a dependency, with no deps of their own
    all-deps: copy []
    foreach [k v] data [append all-deps v]
    foreach item unique all-deps [
        unless find data item [data/:item: copy []]         ;; leaf node, no deps
    ]

    result: copy [] ;; one sorted block per dependency level
    forever [
        ordered: copy []
        foreach [k v] data [if empty? v [append ordered k]] ;; nodes with no remaining deps
        if empty? ordered [break]                           ;; nothing left to peel off
        append/only result new-line/all sort ordered off    ;; record this level

        new-data: make map! []     ;; next round: drop resolved nodes, their deps satisfied
        foreach [k v] data [
            unless find ordered k [new-data/:k: exclude v ordered]
        ]
        data: new-data
    ]

    assert [empty? data "cyclic dependency exists amongst"] ;; leftover data means a cycle
    new-line/all result on
]

probe toposort #[
    des_system_lib: [std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee]
    dw01:           [ieee dw01 dware gtech]
    dw02:           [ieee dw02 dware]
    dw03:           [std synopsys dware dw03 dw02 dw01 ieee gtech]
    dw04:           [dw04 ieee dw01 dware gtech]
    dw05:           [dw05 ieee dware]
    dw06:           [dw06 ieee dware]
    dw07:           [ieee dware]
    dware:          [ieee dware]
    gtech:          [ieee gtech]
    ramlib:         [std ieee]
    std_cell_lib:   [ieee std_cell_lib]
    synopsys:       []
]

Output:

[
    [ieee std synopsys]
    [dware gtech ramlib std_cell_lib]
    [dw01 dw02 dw05 dw06 dw07]
    [des_system_lib dw03 dw04]
]