Topological sort: Difference between revisions

Content added Content deleted
m (→‎{{header|Object Pascal}}: changed highlighter from "Object Pascal" to pascal)
m (syntax highlighting fixup automation)
Line 56: Line 56:
{{trans|Python}}
{{trans|Python}}


<lang 11l>V data = [
<syntaxhighlight lang="11l">V data = [
‘des_system_lib’ = Set(‘std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee’.split(‘ ’)),
‘des_system_lib’ = Set(‘std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee’.split(‘ ’)),
‘dw01’ = Set(‘ieee dw01 dware gtech’.split(‘ ’)),
‘dw01’ = Set(‘ieee dw01 dware gtech’.split(‘ ’)),
Line 104: Line 104:
R r
R r


print(toposort2(&data).join("\n"))</lang>
print(toposort2(&data).join("\n"))</syntaxhighlight>


{{out}}
{{out}}
Line 120: Line 120:
The specification:
The specification:


<lang Ada>with Ada.Containers.Vectors; use Ada.Containers;
<syntaxhighlight lang="ada">with Ada.Containers.Vectors; use Ada.Containers;


package Digraphs is
package Digraphs is
Line 171: Line 171:
type Graph_Type is new Conn_Vec.Vector with null record;
type Graph_Type is new Conn_Vec.Vector with null record;


end Digraphs;</lang>
end Digraphs;</syntaxhighlight>


The implementation:
The implementation:


<lang Ada>package body Digraphs is
<syntaxhighlight lang="ada">package body Digraphs is


function Node_Count(Graph: Graph_Type) return Node_Idx_With_Null is
function Node_Count(Graph: Graph_Type) return Node_Idx_With_Null is
Line 280: Line 280:
end Top_Sort;
end Top_Sort;


end Digraphs;</lang>
end Digraphs;</syntaxhighlight>


'''Set_of_Names: Translating strings into numbers and vice versa'''
'''Set_of_Names: Translating strings into numbers and vice versa'''
Line 286: Line 286:
The specification:
The specification:


<lang Ada>private with Ada.Containers.Indefinite_Vectors;
<syntaxhighlight lang="ada">private with Ada.Containers.Indefinite_Vectors;


generic
generic
Line 327: Line 327:
type Set is new Vecs.Vector with null record;
type Set is new Vecs.Vector with null record;


end Set_Of_Names;</lang>
end Set_Of_Names;</syntaxhighlight>


The implementation
The implementation


<lang Ada>package body Set_Of_Names is
<syntaxhighlight lang="ada">package body Set_Of_Names is


use type Ada.Containers.Count_Type, Vecs.Cursor;
use type Ada.Containers.Count_Type, Vecs.Cursor;
Line 398: Line 398:
end Name;
end Name;


end Set_Of_Names;</lang>
end Set_Of_Names;</syntaxhighlight>


'''Toposort: Putting things together for the main program'''
'''Toposort: Putting things together for the main program'''


<lang Ada>with Ada.Text_IO, Digraphs, Set_Of_Names, Ada.Command_Line;
<syntaxhighlight lang="ada">with Ada.Text_IO, Digraphs, Set_Of_Names, Ada.Command_Line;


procedure Toposort is
procedure Toposort is
Line 484: Line 484:
TIO.Put_Line("There is no topological sorting -- the Graph is cyclic!");
TIO.Put_Line("There is no topological sorting -- the Graph is cyclic!");
end;
end;
end Toposort;</lang>
end Toposort;</syntaxhighlight>


{{out}}
{{out}}
Line 496: Line 496:


=={{header|Bracmat}}==
=={{header|Bracmat}}==
<lang bracmat>( ("des_system_lib".std synopsys "std_cell_lib" "des_system_lib" dw02 dw01 ramlib ieee)
<syntaxhighlight lang="bracmat">( ("des_system_lib".std synopsys "std_cell_lib" "des_system_lib" dw02 dw01 ramlib ieee)
(dw01.ieee dw01 dware gtech)
(dw01.ieee dw01 dware gtech)
(dw02.ieee dw02 dware)
(dw02.ieee dw02 dware)
Line 544: Line 544:
& out$("
& out$("
compile order:" !indeps !res "\ncycles:" !cycles)
compile order:" !indeps !res "\ncycles:" !cycles)
);</lang>
);</syntaxhighlight>
{{out}}
{{out}}
<pre>compile order:
<pre>compile order:
Line 571: Line 571:
=={{header|C}}==
=={{header|C}}==
Parses a multiline string and show the compile order. Note that four lines were added to the example input to form two separate cycles. Code is a little ugly.
Parses a multiline string and show the compile order. Note that four lines were added to the example input to form two separate cycles. Code is a little ugly.
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
Line 692: Line 692:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}} (items on the same row can be compiled together)<lang>Compile order:
{{out}} (items on the same row can be compiled together)<syntaxhighlight lang="text">Compile order:
[unorderable] cycle_21 cycle_22
[unorderable] cycle_21 cycle_22
[unorderable] cycle_11 cycle_12
[unorderable] cycle_11 cycle_12
Line 699: Line 699:
2: std_cell_lib ramlib dware gtech
2: std_cell_lib ramlib dware gtech
3: dw02 dw01 dw05 dw06 dw07
3: dw02 dw01 dw05 dw06 dw07
4: des_system_lib dw03 dw04</lang>
4: des_system_lib dw03 dw04</syntaxhighlight>


=={{header|C sharp}}==
=={{header|C sharp}}==
<lang csharp>
<syntaxhighlight lang="csharp">
namespace Algorithms
namespace Algorithms
{
{
Line 843: Line 843:
}
}


</syntaxhighlight>
</lang>


{{out}}<lang>B - depends on none
{{out}}<syntaxhighlight lang="text">B - depends on none
D - depends on none
D - depends on none
G - depends on none
G - depends on none
Line 854: Line 854:
C - depends on D and E
C - depends on D and E
A - depends on B and C
A - depends on B and C
exiting...</lang>
exiting...</syntaxhighlight>
{{out}}(with cycled dependency)<lang>Cycled dependencies detected: A C D
{{out}}(with cycled dependency)<syntaxhighlight lang="text">Cycled dependencies detected: A C D
exiting...</lang>
exiting...</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
===C++11===
===C++11===
<lang cpp>#include <map>
<syntaxhighlight lang="cpp">#include <map>
#include <set>
#include <set>


Line 996: Line 996:
display_results(string(iterator(file), iterator()));
display_results(string(iterator(file), iterator()));
}
}
}</lang>
}</syntaxhighlight>


===C++17===
===C++17===
<lang cpp>#include <unordered_map>
<syntaxhighlight lang="cpp">#include <unordered_map>
#include <unordered_set>
#include <unordered_set>
#include <vector>
#include <vector>
Line 1,147: Line 1,147:


return 0;
return 0;
}</lang>
}</syntaxhighlight>


{{out}}<lang>I - depends on none
{{out}}<syntaxhighlight lang="text">I - depends on none
H - depends on none
H - depends on none
G - depends on none
G - depends on none
Line 1,167: Line 1,167:
G - destroyed
G - destroyed
H - destroyed
H - destroyed
I - destroyed</lang>
I - destroyed</syntaxhighlight>
{{out}}(with cycled dependency)<lang>Cycled dependencies detected: A D C
{{out}}(with cycled dependency)<syntaxhighlight lang="text">Cycled dependencies detected: A D C
exiting...
exiting...
A - destroyed
A - destroyed
Line 1,178: Line 1,178:
G - destroyed
G - destroyed
H - destroyed
H - destroyed
I - destroyed</lang>
I - destroyed</syntaxhighlight>


=={{header|Clojure}}==
=={{header|Clojure}}==
Line 1,192: Line 1,192:


=====Implementation=====
=====Implementation=====
<lang clojure>(use 'clojure.set)
<syntaxhighlight lang="clojure">(use 'clojure.set)
(use 'clojure.contrib.seq-utils)
(use 'clojure.contrib.seq-utils)


Line 1,264: Line 1,264:
[items]
[items]
(topo-sort-deps (deps items)))
(topo-sort-deps (deps items)))
</syntaxhighlight>
</lang>


Examples of sortable and non-sortable data:
Examples of sortable and non-sortable data:


<lang clojure>(def good-sample
<syntaxhighlight lang="clojure">(def good-sample
'(:des_system_lib (:std :synopsys :std_cell_lib :des_system_lib :dw02 :dw01 :ramlib :ieee)
'(:des_system_lib (:std :synopsys :std_cell_lib :des_system_lib :dw02 :dw01 :ramlib :ieee)
:dw01 (:ieee :dw01 :dware :gtech)
:dw01 (:ieee :dw01 :dware :gtech)
Line 1,287: Line 1,287:


(def bad-sample
(def bad-sample
(concat cyclic-dependence good-sample))</lang>
(concat cyclic-dependence good-sample))</syntaxhighlight>


====={{out}}=====
====={{out}}=====
<lang clojure>Clojure 1.1.0
<syntaxhighlight lang="clojure">Clojure 1.1.0
1:1 user=> #<Namespace topo>
1:1 user=> #<Namespace topo>
1:2 topo=> (topo-sort good-sample)
1:2 topo=> (topo-sort good-sample)
(:std :synopsys :ieee :gtech :ramlib :dware :std_cell_lib :dw07 :dw06 :dw05 :dw01 :dw02 :des_system_lib :dw03 :dw04)
(:std :synopsys :ieee :gtech :ramlib :dware :std_cell_lib :dw07 :dw06 :dw05 :dw01 :dw02 :des_system_lib :dw03 :dw04)
1:3 topo=> (topo-sort bad-sample)
1:3 topo=> (topo-sort bad-sample)
"ERROR: cycles remain among (:dw01 :dw04 :dw03 :des_system_lib)"</lang>
"ERROR: cycles remain among (:dw01 :dw04 :dw03 :des_system_lib)"</syntaxhighlight>


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<lang coffeescript>
<syntaxhighlight lang="coffeescript">
toposort = (targets) ->
toposort = (targets) ->
# targets is hash of sets, where keys are parent nodes and
# targets is hash of sets, where keys are parent nodes and
Line 1,395: Line 1,395:
console.log toposort targets
console.log toposort targets
</syntaxhighlight>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==


<lang lisp>(defun topological-sort (graph &key (test 'eql))
<syntaxhighlight lang="lisp">(defun topological-sort (graph &key (test 'eql))
"Graph is an association list whose keys are objects and whose
"Graph is an association list whose keys are objects and whose
values are lists of objects on which the corresponding key depends.
values are lists of objects on which the corresponding key depends.
Line 1,445: Line 1,445:
all-sorted-p
all-sorted-p
(unless all-sorted-p
(unless all-sorted-p
entries)))))))</lang>
entries)))))))</syntaxhighlight>


Provided example in which all items can be sorted:
Provided example in which all items can be sorted:


<lang lisp>> (defparameter *dependency-graph*
<syntaxhighlight lang="lisp">> (defparameter *dependency-graph*
'((des-system-lib std synopsys std-cell-lib des-system-lib dw02 dw01 ramlib ieee)
'((des-system-lib std synopsys std-cell-lib des-system-lib dw02 dw01 ramlib ieee)
(dw01 ieee dw01 dware gtech)
(dw01 ieee dw01 dware gtech)
Line 1,468: Line 1,468:
(IEEE DWARE DW02 DW05 DW06 DW07 GTECH DW01 DW04 STD-CELL-LIB SYNOPSYS STD DW03 RAMLIB DES-SYSTEM-LIB)
(IEEE DWARE DW02 DW05 DW06 DW07 GTECH DW01 DW04 STD-CELL-LIB SYNOPSYS STD DW03 RAMLIB DES-SYSTEM-LIB)
T
T
NIL</lang>
NIL</syntaxhighlight>


Provided example with <code>dw04</code> added to the dependencies of <code>dw01</code>. Some vertices are ordered, but the second return is <code>nil</code>, indicating that not all vertices could be sorted. The third return value is the hash table containing entries for the four vertices that couldn't be sorted. (The variable <code>[http://www.lispworks.com/documentation/HyperSpec/Body/v_sl_sls.htm /]</code> stores the list of values produced by the last form, and <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_descri.htm describe]</code> prints information about an object.)
Provided example with <code>dw04</code> added to the dependencies of <code>dw01</code>. Some vertices are ordered, but the second return is <code>nil</code>, indicating that not all vertices could be sorted. The third return value is the hash table containing entries for the four vertices that couldn't be sorted. (The variable <code>[http://www.lispworks.com/documentation/HyperSpec/Body/v_sl_sls.htm /]</code> stores the list of values produced by the last form, and <code>[http://www.lispworks.com/documentation/HyperSpec/Body/f_descri.htm describe]</code> prints information about an object.)


<lang lisp>> (defparameter *dependency-graph*
<syntaxhighlight lang="lisp">> (defparameter *dependency-graph*
'((des-system-lib std synopsys std-cell-lib des-system-lib dw02 dw01 ramlib ieee)
'((des-system-lib std synopsys std-cell-lib des-system-lib dw02 dw01 ramlib ieee)
(dw01 ieee dw01 dw04 dware gtech)
(dw01 ieee dw01 dw04 dware gtech)
Line 1,499: Line 1,499:
DW04 (1 DW01)
DW04 (1 DW01)
DW03 (1)
DW03 (1)
DES-SYSTEM-LIB (1)</lang>
DES-SYSTEM-LIB (1)</syntaxhighlight>


=={{header|Crystal}}==
=={{header|Crystal}}==
<lang crystal>def dfs_topo_visit(n, g, tmp, permanent, l)
<syntaxhighlight lang="crystal">def dfs_topo_visit(n, g, tmp, permanent, l)
if permanent.includes?(n)
if permanent.includes?(n)
return
return
Line 1,576: Line 1,576:
puts ""
puts ""
puts dfs_topo_sort(build_graph(data + circular_deps)).join(" -> ")
puts dfs_topo_sort(build_graph(data + circular_deps)).join(" -> ")
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,587: Line 1,587:
=={{header|D}}==
=={{header|D}}==
{{trans|Python}}
{{trans|Python}}
<lang d>import std.stdio, std.string, std.algorithm, std.range;
<syntaxhighlight lang="d">import std.stdio, std.string, std.algorithm, std.range;


final class ArgumentException : Exception {
final class ArgumentException : Exception {
Line 1,660: Line 1,660:
foreach (const subOrder; depw.topoSort) // Should throw.
foreach (const subOrder; depw.topoSort) // Should throw.
subOrder.writeln;
subOrder.writeln;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>#1 : ["ieee", "std", "synopsys"]
<pre>#1 : ["ieee", "std", "synopsys"]
Line 1,674: Line 1,674:
=={{header|E}}==
=={{header|E}}==


<lang e>def makeQueue := <elib:vat.makeQueue>
<syntaxhighlight lang="e">def makeQueue := <elib:vat.makeQueue>


def topoSort(data :Map[any, Set[any]]) {
def topoSort(data :Map[any, Set[any]]) {
Line 1,722: Line 1,722:
return result
return result
}</lang>
}</syntaxhighlight>


<lang e>pragma.enable("accumulator")
<syntaxhighlight lang="e">pragma.enable("accumulator")


def dataText := "\
def dataText := "\
Line 1,744: Line 1,744:
def data := accum [].asMap() for rx`(@item.{17})(@deps.*)` in dataText.split("\n") { _.with(item.trim(), deps.split(" ").asSet()) }
def data := accum [].asMap() for rx`(@item.{17})(@deps.*)` in dataText.split("\n") { _.with(item.trim(), deps.split(" ").asSet()) }


println(topoSort(data))</lang>
println(topoSort(data))</syntaxhighlight>


{{out}}
{{out}}
Line 1,754: Line 1,754:
''' Data
''' Data


<lang lisp>
<syntaxhighlight lang="lisp">
(define dependencies
(define dependencies
'((des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee)
'((des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee)
Line 1,781: Line 1,781:
(define (add-dependencies g dep-list)
(define (add-dependencies g dep-list)
(for* ((dep dep-list) (b (rest dep))) (a->b g b (first dep))))
(for* ((dep dep-list) (b (rest dep))) (a->b g b (first dep))))
</syntaxhighlight>
</lang>
'''Implementation
'''Implementation


Remove all vertices with in-degree = 0, until to one left. (in-degree = number of arrows to a vertex)
Remove all vertices with in-degree = 0, until to one left. (in-degree = number of arrows to a vertex)
<lang lisp>
<syntaxhighlight lang="lisp">
;; topological sort
;; topological sort
;;
;;
Line 1,818: Line 1,818:
(error " ♻️ t-sort:cyclic" (map vertex-label (graph-cycle g))))))
(error " ♻️ t-sort:cyclic" (map vertex-label (graph-cycle g))))))


</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<lang lisp>
<syntaxhighlight lang="lisp">
(define g (make-graph "VHDL"))
(define g (make-graph "VHDL"))
(add-dependencies g dependencies)
(add-dependencies g dependencies)
Line 1,834: Line 1,834:
t-sort (std synopsys ieee dware dw02 dw05 dw06 dw07 gtech ramlib std_cell_lib)
t-sort (std synopsys ieee dware dw02 dw05 dw06 dw07 gtech ramlib std_cell_lib)
⛔️ error: ♻️ t-sort:cyclic (dw04 dw01)
⛔️ error: ♻️ t-sort:cyclic (dw04 dw01)
</syntaxhighlight>
</lang>


=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Erlang}}
{{trans|Erlang}}
<lang elixir>defmodule Topological do
<syntaxhighlight lang="elixir">defmodule Topological do
def sort(library) do
def sort(library) do
g = :digraph.new
g = :digraph.new
Line 1,883: Line 1,883:
IO.puts ""
IO.puts ""
bad_libraries = Keyword.update!(libraries, :dw01, &[:dw04 | &1])
bad_libraries = Keyword.update!(libraries, :dw01, &[:dw04 | &1])
Topological.sort(bad_libraries)</lang>
Topological.sort(bad_libraries)</syntaxhighlight>


{{out}}
{{out}}
Line 1,895: Line 1,895:


=={{header|Erlang}}==
=={{header|Erlang}}==
<lang erlang>
<syntaxhighlight lang="erlang">
-module(topological_sort).
-module(topological_sort).
-compile(export_all).
-compile(export_all).
Line 1,967: Line 1,967:
digraph:add_vertex(G,D), % noop if dependency already added
digraph:add_vertex(G,D), % noop if dependency already added
digraph:add_edge(G,D,L). % Dependencies represented as an edge D -> L
digraph:add_edge(G,D,L). % Dependencies represented as an edge D -> L
</syntaxhighlight>
</lang>


{{out}}
{{out}}
<lang erlang>
<syntaxhighlight lang="erlang">
62> topological_sort:main().
62> topological_sort:main().
synopsys -> std -> ieee -> dware -> dw02 -> dw05 -> ramlib -> std_cell_lib -> dw06 -> dw07 -> gtech -> dw01 -> des_system_lib -> dw03 -> dw04
synopsys -> std -> ieee -> dware -> dw02 -> dw05 -> ramlib -> std_cell_lib -> dw06 -> dw07 -> gtech -> dw01 -> des_system_lib -> dw03 -> dw04
Line 1,976: Line 1,976:
dw04 -> dw01 -> dw04
dw04 -> dw01 -> dw04
dw01 -> dw04 -> dw01
dw01 -> dw04 -> dw01
ok</lang>
ok</syntaxhighlight>


Erlang has a built in digraph library and datastructure. ''digraph_utils'' contains the ''top_sort'' function which provides a topological sort of the vertices or returns false if it's not possible (due to circular references).
Erlang has a built in digraph library and datastructure. ''digraph_utils'' contains the ''top_sort'' function which provides a topological sort of the vertices or returns false if it's not possible (due to circular references).
Line 2,018: Line 2,018:


{{works with|Gforth}}
{{works with|Gforth}}
<lang forth>variable nodes 0 nodes ! \ linked list of nodes
<syntaxhighlight lang="forth">variable nodes 0 nodes ! \ linked list of nodes


: node. ( body -- )
: node. ( body -- )
Line 2,088: Line 2,088:
deps dw01 ieee dw01 dware gtech dw04
deps dw01 ieee dw01 dware gtech dw04


all-nodes</lang>
all-nodes</syntaxhighlight>


{{out}}
{{out}}
Line 2,103: Line 2,103:
This implementation is not optimal: for each ''level'' of dependency (for example A -> B -> C counts as three levels), there is a loop through all dependencies in IDEP.
This implementation is not optimal: for each ''level'' of dependency (for example A -> B -> C counts as three levels), there is a loop through all dependencies in IDEP.
It would be possible to optimize a bit, without changing the main idea, by first sorting IDEP according to first column, and using more temporary space, keeping track of where is located data in IDEP for each library (all dependencies of a same library being grouped).
It would be possible to optimize a bit, without changing the main idea, by first sorting IDEP according to first column, and using more temporary space, keeping track of where is located data in IDEP for each library (all dependencies of a same library being grouped).
<lang fortran> SUBROUTINE TSORT(NL,ND,IDEP,IORD,IPOS,NO)
<syntaxhighlight lang="fortran"> SUBROUTINE TSORT(NL,ND,IDEP,IORD,IPOS,NO)
IMPLICIT NONE
IMPLICIT NONE
INTEGER NL,ND,NO,IDEP(ND,2),IORD(NL),IPOS(NL),I,J,K,IL,IR,IPL,IPR
INTEGER NL,ND,NO,IDEP(ND,2),IORD(NL),IPOS(NL),I,J,K,IL,IR,IPL,IPR
Line 2,126: Line 2,126:
IF(K.GT.J) GO TO 20
IF(K.GT.J) GO TO 20
NO=J-1
NO=J-1
END</lang>
END</syntaxhighlight>


An example. Dependencies are encoded to make program shorter (in array ICODE).
An example. Dependencies are encoded to make program shorter (in array ICODE).


<lang fortran> PROGRAM EX_TSORT
<syntaxhighlight lang="fortran"> PROGRAM EX_TSORT
IMPLICIT NONE
IMPLICIT NONE
INTEGER NL,ND,NC,NO,IDEP,IORD,IPOS,ICODE,I,J,IL,IR
INTEGER NL,ND,NC,NO,IDEP,IORD,IPOS,ICODE,I,J,IL,IR
Line 2,167: Line 2,167:
DO 50 I=NO+1,NL
DO 50 I=NO+1,NL
50 PRINT*,LABEL(IORD(I))
50 PRINT*,LABEL(IORD(I))
END</lang>
END</syntaxhighlight>


{{out}}
{{out}}
Line 2,212: Line 2,212:
===Modern Fortran===
===Modern Fortran===
A modern Fortran (95-2008) version of the TSORT subroutine is shown here (note that the IPOS array is not an input).
A modern Fortran (95-2008) version of the TSORT subroutine is shown here (note that the IPOS array is not an input).
<lang fortran>subroutine tsort(nl,nd,idep,iord,no)
<syntaxhighlight lang="fortran">subroutine tsort(nl,nd,idep,iord,no)


implicit none
implicit none
Line 2,249: Line 2,249:


end subroutine tsort
end subroutine tsort
</syntaxhighlight>
</lang>


=={{header|FunL}}==
=={{header|FunL}}==
<lang funl>def topsort( graph ) =
<syntaxhighlight lang="funl">def topsort( graph ) =
val L = seq()
val L = seq()
val S = seq()
val S = seq()
Line 2,312: Line 2,312:
case topsort( graph ) of
case topsort( graph ) of
None -> println( 'un-orderable' )
None -> println( 'un-orderable' )
Some( ordering ) -> println( ordering )</lang>
Some( ordering ) -> println( ordering )</syntaxhighlight>


{{out}}
{{out}}
Line 2,322: Line 2,322:
=={{header|Go}}==
=={{header|Go}}==
===Kahn===
===Kahn===
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 2,461: Line 2,461:
}
}
return L, nil
return L, nil
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,473: Line 2,473:
Topological sort only, this function can replace topSortKahn in above program. The
Topological sort only, this function can replace topSortKahn in above program. The
in-degree list is not needed.
in-degree list is not needed.
<lang go>// General purpose topological sort, not specific to the application of
<syntaxhighlight lang="go">// General purpose topological sort, not specific to the application of
// library dependencies. Also adapted from Wikipedia pseudo code.
// library dependencies. Also adapted from Wikipedia pseudo code.
func topSortDFS(g graph) (order, cyclic []string) {
func topSortDFS(g graph) (order, cyclic []string) {
Line 2,520: Line 2,520:
}
}
return L, nil
return L, nil
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
(when used in program of Kahn example.)
(when used in program of Kahn example.)
Line 2,532: Line 2,532:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>import Data.List ((\\), elemIndex, intersect, nub)
<syntaxhighlight lang="haskell">import Data.List ((\\), elemIndex, intersect, nub)
import Data.Bifunctor (bimap, first)
import Data.Bifunctor (bimap, first)


Line 2,575: Line 2,575:


main :: IO ()
main :: IO ()
main = print $ toposort depLibs</lang>
main = print $ toposort depLibs</syntaxhighlight>
{{out}}
{{out}}
<lang haskell>*Main> toposort depLibs
<syntaxhighlight lang="haskell">*Main> toposort depLibs
["std","synopsys","ieee","std_cell_lib","dware","dw02","gtech","dw01","ramlib","des_system_lib","dw03","dw04","dw05","dw06","dw07"]
["std","synopsys","ieee","std_cell_lib","dware","dw02","gtech","dw01","ramlib","des_system_lib","dw03","dw04","dw05","dw06","dw07"]


*Main> toposort $ (\(xs,(k,ks):ys) -> xs++ (k,ks++" dw04"):ys) $ splitAt 1 depLibs
*Main> toposort $ (\(xs,(k,ks):ys) -> xs++ (k,ks++" dw04"):ys) $ splitAt 1 depLibs
*** Exception: Dependency cycle detected for libs [["dw01","dw04"]]</lang>
*** Exception: Dependency cycle detected for libs [["dw01","dw04"]]</syntaxhighlight>


=={{header|Huginn}}==
=={{header|Huginn}}==
<lang huginn>import Algorithms as algo;
<syntaxhighlight lang="huginn">import Algorithms as algo;
import Text as text;
import Text as text;


Line 2,656: Line 2,656:
dfs = DepthFirstSearch();
dfs = DepthFirstSearch();
print( "{}\n".format( dfs.topological_sort( dg ) ) );
print( "{}\n".format( dfs.topological_sort( dg ) ) );
}</lang>
}</syntaxhighlight>


==Icon and Unicon==
==Icon and Unicon==
Line 2,669: Line 2,669:
elements have been built.
elements have been built.


<lang icon>record graph(nodes,arcs)
<syntaxhighlight lang="icon">record graph(nodes,arcs)
global ex_name, in_name
global ex_name, in_name


Line 2,783: Line 2,783:
g.arcs ? while arc := move(2) do if arc[1] == f then t ++:= arc[2]
g.arcs ? while arc := move(2) do if arc[1] == f then t ++:= arc[2]
return t
return t
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 2,810: Line 2,810:
in parallel once the elements in the preceding lines have been built.
in parallel once the elements in the preceding lines have been built.


<lang icon>record graph(nodes,arcs)
<syntaxhighlight lang="icon">record graph(nodes,arcs)


procedure main()
procedure main()
Line 2,896: Line 2,896:
while (af := @cp, at := @cp) do if af == f then insert(t, at)
while (af := @cp, at := @cp) do if af == f then insert(t, at)
return t
return t
end</lang>
end</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==


<lang J>dependencySort=: monad define
<syntaxhighlight lang="j">dependencySort=: monad define
parsed=. <@;:;._2 y
parsed=. <@;:;._2 y
names=. {.&>parsed
names=. {.&>parsed
Line 2,907: Line 2,907:
assert.-.1 e. (<0 1)|:depends
assert.-.1 e. (<0 1)|:depends
(-.&names ~.;parsed),names /: +/"1 depends
(-.&names ~.;parsed),names /: +/"1 depends
)</lang>
)</syntaxhighlight>


With the sample data set:
With the sample data set:
Line 2,929: Line 2,929:
We would get:
We would get:


<lang J> >dependencySort dependencies
<syntaxhighlight lang="j"> >dependencySort dependencies
std
std
ieee
ieee
Line 2,944: Line 2,944:
dw04
dw04
dw03
dw03
des_system_lib</lang>
des_system_lib</syntaxhighlight>


If we tried to also make dw01 depend on dw04, the sort would fail because of the circular dependency:
If we tried to also make dw01 depend on dw04, the sort would fail because of the circular dependency:


<lang J> dependencySort dependencies,'dw01 dw04',LF
<syntaxhighlight lang="j"> dependencySort dependencies,'dw01 dw04',LF
|assertion failure: dependencySort
|assertion failure: dependencySort
| -.1 e.(<0 1)|:depends</lang>
| -.1 e.(<0 1)|:depends</syntaxhighlight>


Here is an alternate implementation which uses a slightly different representation for the dependencies (instead of a boolean connection matrix to represent connections, we use a list of lists of indices to represent connections):
Here is an alternate implementation which uses a slightly different representation for the dependencies (instead of a boolean connection matrix to represent connections, we use a list of lists of indices to represent connections):


<lang J>depSort=: monad define
<syntaxhighlight lang="j">depSort=: monad define
parsed=. <@;:;._2 y
parsed=. <@;:;._2 y
names=. {.&>parsed
names=. {.&>parsed
Line 2,961: Line 2,961:
assert.-.1 e. (i.@# e.S:0"0 ])depends
assert.-.1 e. (i.@# e.S:0"0 ])depends
(-.&names ~.;parsed),names /: #@> depends
(-.&names ~.;parsed),names /: #@> depends
)</lang>
)</syntaxhighlight>


It's results are identical to the first implementation, but this might be more efficient in typical cases.
It's results are identical to the first implementation, but this might be more efficient in typical cases.
Line 2,967: Line 2,967:
=={{header|Java}}==
=={{header|Java}}==
{{works with|Java|7}}
{{works with|Java|7}}
<lang java>import java.util.*;
<syntaxhighlight lang="java">import java.util.*;


public class TopologicalSort {
public class TopologicalSort {
Line 3,043: Line 3,043:
return false;
return false;
}
}
}</lang>
}</syntaxhighlight>


<pre>[std, ieee, dware, dw02, dw05, dw06, dw07, gtech, dw01, dw04, ramlib, std_cell_lib, synopsys, des_system_lib, dw03]</pre>
<pre>[std, ieee, dware, dw02, dw05, dw06, dw07, gtech, dw01, dw04, ramlib, std_cell_lib, synopsys, des_system_lib, dw03]</pre>
Line 3,051: Line 3,051:
====ES6====
====ES6====


<lang JavaScript>const libs =
<syntaxhighlight lang="javascript">const libs =
`des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
`des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
dw01 ieee dw01 dware gtech
dw01 ieee dw01 dware gtech
Line 3,108: Line 3,108:


console.log('Solution:', S);
console.log('Solution:', S);
</lang>
</syntaxhighlight>


Output:
Output:
<syntaxhighlight lang="javascript">
<lang JavaScript>
Solution: [
Solution: [
'ieee',
'ieee',
Line 3,128: Line 3,128:
'dw03',
'dw03',
'des_system_lib' ]
'des_system_lib' ]
</syntaxhighlight>
</lang>


=={{header|jq}}==
=={{header|jq}}==
Line 3,149: Line 3,149:


To solve and print the solution to the given problem on a 1GHz machine takes about 5ms.
To solve and print the solution to the given problem on a 1GHz machine takes about 5ms.
<lang jq># independent/0 emits an array of the dependencies that have no dependencies
<syntaxhighlight lang="jq"># independent/0 emits an array of the dependencies that have no dependencies
# Input: an object representing a normalized dependency graph
# Input: an object representing a normalized dependency graph
def independent:
def independent:
Line 3,199: Line 3,199:
normalize | [[], .] | _tsort ;
normalize | [[], .] | _tsort ;


tsort</lang>
tsort</syntaxhighlight>
Data:
Data:
<lang json>{"des_system_lib": [ "std", "synopsys", "std_cell_lib", "des_system_lib", "dw02", "dw01", "ramlib", "ieee"],
<syntaxhighlight lang="json">{"des_system_lib": [ "std", "synopsys", "std_cell_lib", "des_system_lib", "dw02", "dw01", "ramlib", "ieee"],
"dw01": [ "ieee", "dw01", "dware", "gtech"],
"dw01": [ "ieee", "dw01", "dware", "gtech"],
"dw02": [ "ieee", "dw02", "dware"],
"dw02": [ "ieee", "dw02", "dware"],
Line 3,215: Line 3,215:
"synopsys": []
"synopsys": []
}
}
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<syntaxhighlight lang="jq">
<lang jq>
$ jq -c -f tsort.jq tsort.json
$ jq -c -f tsort.jq tsort.json
["ieee","std","synopsys","dware","gtech","ramlib","std_cell_lib","dw01","dw02","des_system_lib","dw03","dw04","dw05","dw06","dw07"]
["ieee","std","synopsys","dware","gtech","ramlib","std_cell_lib","dw01","dw02","des_system_lib","dw03","dw04","dw05","dw06","dw07"]
</syntaxhighlight>
</lang>


=={{header|Julia}}==
=={{header|Julia}}==
Line 3,226: Line 3,226:
{{trans|Python}}
{{trans|Python}}


<lang julia>function toposort(data::Dict{T,Set{T}}) where T
<syntaxhighlight lang="julia">function toposort(data::Dict{T,Set{T}}) where T
data = copy(data)
data = copy(data)
for (k, v) in data
for (k, v) in data
Line 3,262: Line 3,262:
)
)


println("# Topologically sorted:\n - ", join(toposort(data), "\n - "))</lang>
println("# Topologically sorted:\n - ", join(toposort(data), "\n - "))</syntaxhighlight>


{{out}}
{{out}}
Line 3,284: Line 3,284:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|Java}}
{{trans|Java}}
<lang scala>// version 1.1.51
<syntaxhighlight lang="scala">// version 1.1.51


val s = "std, ieee, des_system_lib, dw01, dw02, dw03, dw04, dw05, " +
val s = "std, ieee, des_system_lib, dw01, dw02, dw03, dw04, dw05, " +
Line 3,351: Line 3,351:
println("Following the addition of dw04 to the dependencies of dw01:")
println("Following the addition of dw04 to the dependencies of dw01:")
println(g2.topoSort())
println(g2.topoSort())
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,367: Line 3,367:
This version follows python implementation and returns List of Lists which is useful for parallel execution for example
This version follows python implementation and returns List of Lists which is useful for parallel execution for example
</pre>
</pre>
<lang scala>
<syntaxhighlight lang="scala">
val graph = mapOf(
val graph = mapOf(
"des_system_lib" to "std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee".split(" ").toSet(),
"des_system_lib" to "std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee".split(" ").toSet(),
Line 3,420: Line 3,420:
}
}


</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 3,432: Line 3,432:


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<lang M2000 Interpreter>Module testthis {
<syntaxhighlight lang="m2000 interpreter">Module testthis {
\\ empty stack
\\ empty stack
Flush
Flush
Line 3,529: Line 3,529:
}
}
testthis
testthis
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 3,541: Line 3,541:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Work in Mathematica 8 or higher versions.
Work in Mathematica 8 or higher versions.
<lang mathematica>TopologicalSort[
<syntaxhighlight lang="mathematica">TopologicalSort[
Graph[Flatten[# /. {l_, ld_} :>
Graph[Flatten[# /. {l_, ld_} :>
Map[# -> l &,
Map[# -> l &,
Line 3,559: Line 3,559:
{"ramlib", {"std", "ieee"}},
{"ramlib", {"std", "ieee"}},
{"std_cell_lib", {"ieee", "std_cell_lib"}},
{"std_cell_lib", {"ieee", "std_cell_lib"}},
{"synopsys", {}}}</lang>
{"synopsys", {}}}</syntaxhighlight>
{{Out}}
{{Out}}
<pre>{"ieee", "std_cell_lib", "gtech", "dware", "dw07", "dw06", "dw05", \
<pre>{"ieee", "std_cell_lib", "gtech", "dware", "dw07", "dw06", "dw05", \
Line 3,567: Line 3,567:


=={{header|Mercury}}==
=={{header|Mercury}}==
<syntaxhighlight lang="mercury">
<lang Mercury>
:- module topological_sort.
:- module topological_sort.


Line 3,645: Line 3,645:
print(CompileOrder,!IO).
print(CompileOrder,!IO).


</syntaxhighlight>
</lang>


=={{header|Nim}}==
=={{header|Nim}}==


<lang Nim>import sequtils, strutils, sets, tables, sugar
<syntaxhighlight lang="nim">import sequtils, strutils, sets, tables, sugar


type StringSet = HashSet[string]
type StringSet = HashSet[string]
Line 3,731: Line 3,731:
for key in data.keys: echo key
for key in data.keys: echo key
except ValueError:
except ValueError:
echo getCurrentExceptionMsg()</lang>
echo getCurrentExceptionMsg()</syntaxhighlight>


=={{header|Object Pascal}}==
=={{header|Object Pascal}}==
Written for Free Pascal, but will probably work in Delphi if you change the required units.
Written for Free Pascal, but will probably work in Delphi if you change the required units.
<lang pascal>
<syntaxhighlight lang="pascal">
program topologicalsortrosetta;
program topologicalsortrosetta;


Line 4,148: Line 4,148:
InputList.Free;
InputList.Free;
end.
end.
</syntaxhighlight>
</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==


<lang ocaml>let dep_libs = [
<syntaxhighlight lang="ocaml">let dep_libs = [
("des_system_lib", ["std"; "synopsys"; "std_cell_lib"; "des_system_lib"; "dw02"; "dw01"; "ramlib"; "ieee"]);
("des_system_lib", ["std"; "synopsys"; "std_cell_lib"; "des_system_lib"; "dw02"; "dw01"; "ramlib"; "ieee"]);
("dw01", (*"dw04"::*)["ieee"; "dw01"; "dware"; "gtech"]);
("dw01", (*"dw04"::*)["ieee"; "dw01"; "dware"; "gtech"]);
Line 4,205: Line 4,205:
print_string "result: \n ";
print_string "result: \n ";
print_endline (String.concat ", " res);
print_endline (String.concat ", " res);
;;</lang>
;;</syntaxhighlight>


If dw04 is added to the set of dependencies of dw01 to make the data un-orderable (uncomment it), an exception is raised:
If dw04 is added to the set of dependencies of dw01 to make the data un-orderable (uncomment it), an exception is raised:
Line 4,211: Line 4,211:


=={{header|OxygenBasic}}==
=={{header|OxygenBasic}}==
<lang>
<syntaxhighlight lang="text">
'TOPOLOGICAL SORT
'TOPOLOGICAL SORT


Line 4,428: Line 4,428:
next
next
ret
ret
</syntaxhighlight>
</lang>




=={{header|Oz}}==
=={{header|Oz}}==
Using constraint propagation and search:
Using constraint propagation and search:
<lang oz>declare
<syntaxhighlight lang="oz">declare
Deps = unit(
Deps = unit(
des_system_lib: [std synopsys std_cell_lib des_system_lib
des_system_lib: [std synopsys std_cell_lib des_system_lib
Line 4,518: Line 4,518:
{System.showInfo "\nBONUS - grouped by parallelizable compile jobs:"}
{System.showInfo "\nBONUS - grouped by parallelizable compile jobs:"}
{PrintSolution Sol}
{PrintSolution Sol}
end</lang>
end</syntaxhighlight>


Output:
Output:
Line 4,554: Line 4,554:
The algorithm used allows the output to be clustered; libraries on the same line are all independent (given the building of any previous lines of libraries), and so could be built in parallel.
The algorithm used allows the output to be clustered; libraries on the same line are all independent (given the building of any previous lines of libraries), and so could be built in parallel.


<lang perl>sub print_topo_sort {
<syntaxhighlight lang="perl">sub print_topo_sort {
my %deps = @_;
my %deps = @_;


Line 4,592: Line 4,592:
print_topo_sort(%deps);
print_topo_sort(%deps);
push @{ $deps{'dw01'} }, 'dw04'; # Add unresolvable dependency
push @{ $deps{'dw01'} }, 'dw04'; # Add unresolvable dependency
print_topo_sort(%deps);</lang>
print_topo_sort(%deps);</syntaxhighlight>


Output:<pre>ieee std synopsys
Output:<pre>ieee std synopsys
Line 4,606: Line 4,606:
=={{header|Phix}}==
=={{header|Phix}}==
Implemented as a trivial normal sort.
Implemented as a trivial normal sort.
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">names</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">names</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">RANK</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NAME</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">DEP</span> <span style="color: #000080;font-style:italic;">-- content of names
<span style="color: #008080;">enum</span> <span style="color: #000000;">RANK</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">NAME</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">DEP</span> <span style="color: #000080;font-style:italic;">-- content of names
Line 4,697: Line 4,697:
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nbad input:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nbad input:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">topsort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">input</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"\ndw01 dw04"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">topsort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">input</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"\ndw01 dw04"</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
Items on the same line can be compiled at the same time, and each line is alphabetic.
Items on the same line can be compiled at the same time, and each line is alphabetic.
Line 4,714: Line 4,714:


=={{header|Picat}}==
=={{header|Picat}}==
<lang Picat>topological_sort(Precedences, Sorted) =>
<syntaxhighlight lang="picat">topological_sort(Precedences, Sorted) =>


Edges = [K=V : [K,V] in Precedences],
Edges = [K=V : [K,V] in Precedences],
Line 4,743: Line 4,743:
% deletes all pairs in L where a key is X
% deletes all pairs in L where a key is X
% (this is lessf on a multi-map in GNU SETL)
% (this is lessf on a multi-map in GNU SETL)
delete_key(L,X) = [K=V : K=V in L, K!=X].</lang>
delete_key(L,X) = [K=V : K=V in L, K!=X].</syntaxhighlight>


The approach was inspired by a SETL snippet:
The approach was inspired by a SETL snippet:
Line 4,756: Line 4,756:
===Test without cycles===
===Test without cycles===
Identify and remove the cycles.
Identify and remove the cycles.
<lang Picat>main =>
<syntaxhighlight lang="picat">main =>
deps(1,Deps),
deps(1,Deps),
Prec=[],
Prec=[],
Line 4,782: Line 4,782:
std_cell_lib=[ieee,std_cell_lib],
std_cell_lib=[ieee,std_cell_lib],
synopsys=[]
synopsys=[]
].</lang>
].</syntaxhighlight>


{{out}}
{{out}}
Line 4,788: Line 4,788:


===Test with cycles===
===Test with cycles===
<lang Picat>main =>
<syntaxhighlight lang="picat">main =>
deps(with_cycle,Deps),
deps(with_cycle,Deps),
Prec=[],
Prec=[],
Line 4,819: Line 4,819:
cycle_3=[dw01,cycle_4,dw02,daw03],
cycle_3=[dw01,cycle_4,dw02,daw03],
cycle_4=[cycle_3,dw01,dw04]
cycle_4=[cycle_3,dw01,dw04]
].</lang>
].</syntaxhighlight>


{{out}}
{{out}}
Line 4,830: Line 4,830:


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(de sortDependencies (Lst)
<syntaxhighlight lang="picolisp">(de sortDependencies (Lst)
(setq Lst # Build a flat list
(setq Lst # Build a flat list
(uniq
(uniq
Line 4,844: Line 4,844:
(del (link @) 'Lst) # Yes: Store in result
(del (link @) 'Lst) # Yes: Store in result
(for This Lst # and remove from 'dep's
(for This Lst # and remove from 'dep's
(=: dep (delete @ (: dep))) ) ) ) ) )</lang>
(=: dep (delete @ (: dep))) ) ) ) ) )</syntaxhighlight>
Output:
Output:
<pre>: (sortDependencies
<pre>: (sortDependencies
Line 4,864: Line 4,864:


=={{header|PowerShell}}==
=={{header|PowerShell}}==
<lang PowerShell>#Input Data
<syntaxhighlight lang="powershell">#Input Data
$a=@"
$a=@"
des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
Line 4,962: Line 4,962:
"{0,-14} $($_."Library Dependencies")" -f $_.Library
"{0,-14} $($_."Library Dependencies")" -f $_.Library
}
}
}</lang>
}</syntaxhighlight>


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>#EndOfDataMarker$ = "::EndOfData::"
<syntaxhighlight lang="purebasic">#EndOfDataMarker$ = "::EndOfData::"
DataSection
DataSection
;"LIBRARY: [LIBRARY_DEPENDENCY_1 LIBRARY_DEPENDENCY_2 ... LIBRARY_DEPENDENCY_N]
;"LIBRARY: [LIBRARY_DEPENDENCY_1 LIBRARY_DEPENDENCY_2 ... LIBRARY_DEPENDENCY_N]
Line 5,083: Line 5,083:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
Input()
Input()
CloseConsole()</lang>
CloseConsole()</syntaxhighlight>
Sample output for no dependencies:
Sample output for no dependencies:
<pre>Compile order:
<pre>Compile order:
Line 5,113: Line 5,113:


===Python 3===
===Python 3===
<lang python>try:
<syntaxhighlight lang="python">try:
from functools import reduce
from functools import reduce
except:
except:
Line 5,148: Line 5,148:
assert not data, "A cyclic dependency exists amongst %r" % data
assert not data, "A cyclic dependency exists amongst %r" % data


print ('\n'.join( toposort2(data) ))</lang>
print ('\n'.join( toposort2(data) ))</syntaxhighlight>


'''Ordered output'''<br>
'''Ordered output'''<br>
Line 5,166: Line 5,166:


===Python 3.9 graphlib===
===Python 3.9 graphlib===
<lang python>from graphlib import TopologicalSorter
<syntaxhighlight lang="python">from graphlib import TopologicalSorter


# LIBRARY mapped_to LIBRARY DEPENDENCIES
# LIBRARY mapped_to LIBRARY DEPENDENCIES
Line 5,189: Line 5,189:


ts = TopologicalSorter(data)
ts = TopologicalSorter(data)
print(tuple(ts.static_order()))</lang>
print(tuple(ts.static_order()))</syntaxhighlight>


{{out}}
{{out}}
Line 5,197: Line 5,197:


First make the list
First make the list
<syntaxhighlight lang="r">
<lang R>
deps <- list(
deps <- list(
"des_system_lib" = c("std", "synopsys", "std_cell_lib", "des_system_lib", "dw02", "dw01", "ramlib", "ieee"),
"des_system_lib" = c("std", "synopsys", "std_cell_lib", "des_system_lib", "dw02", "dw01", "ramlib", "ieee"),
Line 5,212: Line 5,212:
"std_cell_lib" = c("ieee", "std_cell_lib"),
"std_cell_lib" = c("ieee", "std_cell_lib"),
"synopsys" = c())
"synopsys" = c())
</syntaxhighlight>
</lang>


Topological sort function. It will throw an error if it cannot complete, printing the list of items which cannot be ordered.
Topological sort function. It will throw an error if it cannot complete, printing the list of items which cannot be ordered.
If it succeeds, returns the list of items in topological order.
If it succeeds, returns the list of items in topological order.
<syntaxhighlight lang="r">
<lang R>
tsort <- function(deps) {
tsort <- function(deps) {
nm <- names(deps)
nm <- names(deps)
Line 5,248: Line 5,248:
s
s
}
}
</syntaxhighlight>
</lang>


On the given example :
On the given example :
<syntaxhighlight lang="r">
<lang R>
tsort(deps)
tsort(deps)
# [1] "std" "ieee" "dware" "gtech" "ramlib"
# [1] "std" "ieee" "dware" "gtech" "ramlib"
# [6] "std_cell_lib" "synopsys" "dw01" "dw02" "dw03"
# [6] "std_cell_lib" "synopsys" "dw01" "dw02" "dw03"
#[11] "dw04" "dw05" "dw06" "dw07" "des_system_lib"
#[11] "dw04" "dw05" "dw06" "dw07" "des_system_lib"
</syntaxhighlight>
</lang>


If dw01 depends on dw04 as well :
If dw01 depends on dw04 as well :


<syntaxhighlight lang="r">
<lang R>
Unorderable items :
Unorderable items :
des_system_lib
des_system_lib
Line 5,266: Line 5,266:
dw04
dw04
dw03
dw03
</syntaxhighlight>
</lang>


=={{header|Racket}}==
=={{header|Racket}}==
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket


Line 5,328: Line 5,328:


(topo-sort (clean G))
(topo-sort (clean G))
</syntaxhighlight>
</lang>
Output:
Output:
<lang racket>
<syntaxhighlight lang="racket">
'(synopsys ieee dware gtech std_cell_lib std ramlib dw07 dw06 dw05 dw01 dw04 dw02 dw03 des_system_lib)
'(synopsys ieee dware gtech std_cell_lib std ramlib dw07 dw06 dw05 dw01 dw04 dw02 dw03 des_system_lib)
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
Line 5,338: Line 5,338:
{{trans|Perl}}
{{trans|Perl}}
{{Works with|rakudo|2016.01}}
{{Works with|rakudo|2016.01}}
<lang perl6>sub print_topo_sort ( %deps ) {
<syntaxhighlight lang="raku" line>sub print_topo_sort ( %deps ) {
my %ba;
my %ba;
for %deps.kv -> $before, @afters {
for %deps.kv -> $before, @afters {
Line 5,374: Line 5,374:
print_topo_sort(%deps);
print_topo_sort(%deps);
%deps<dw01> = <ieee dw01 dware gtech dw04>; # Add unresolvable dependency
%deps<dw01> = <ieee dw01 dware gtech dw04>; # Add unresolvable dependency
print_topo_sort(%deps);</lang>
print_topo_sort(%deps);</syntaxhighlight>


Output:<pre>ieee std synopsys
Output:<pre>ieee std synopsys
Line 5,394: Line 5,394:
Some of the FORTRAN 77 statements were converted to &nbsp; '''do''' &nbsp; loops (or &nbsp; '''do''' &nbsp; structures), &nbsp; and
Some of the FORTRAN 77 statements were converted to &nbsp; '''do''' &nbsp; loops (or &nbsp; '''do''' &nbsp; structures), &nbsp; and
<br>some variables were &nbsp; [https://en.wikipedia.org/wiki/Camel_case <u>''camel capitalized]''</u>.
<br>some variables were &nbsp; [https://en.wikipedia.org/wiki/Camel_case <u>''camel capitalized]''</u>.
<lang rexx>/*REXX pgm does a topological sort (orders such that no item precedes a dependent item).*/
<syntaxhighlight lang="rexx">/*REXX pgm does a topological sort (orders such that no item precedes a dependent item).*/
iDep.= 0; iPos.= 0; iOrd.= 0 /*initialize some stemmed arrays to 0.*/
iDep.= 0; iPos.= 0; iOrd.= 0 /*initialize some stemmed arrays to 0.*/
nL= 15; nd= 44; nc= 69 /* " " "parms" and indices.*/
nL= 15; nd= 44; nc= 69 /* " " "parms" and indices.*/
Line 5,436: Line 5,436:
end /*i*/
end /*i*/
end /*until*/
end /*until*/
nO= j-1; return</lang>
nO= j-1; return</syntaxhighlight>
{{out|output}}
{{out|output}}
<pre>
<pre>
Line 5,463: Line 5,463:
=={{header|Ruby}}==
=={{header|Ruby}}==
Uses the [http://www.ruby-doc.org/stdlib/libdoc/tsort/rdoc/classes/TSort.html TSort] module from the Ruby stdlib.
Uses the [http://www.ruby-doc.org/stdlib/libdoc/tsort/rdoc/classes/TSort.html TSort] module from the Ruby stdlib.
<lang ruby>require 'tsort'
<syntaxhighlight lang="ruby">require 'tsort'
class Hash
class Hash
include TSort
include TSort
Line 5,500: Line 5,500:
ramlib std ieee
ramlib std ieee
std_cell_lib ieee std_cell_lib
std_cell_lib ieee std_cell_lib
synopsys</lang>
synopsys</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,509: Line 5,509:


=={{header|Rust}}==
=={{header|Rust}}==
<lang rust>use std::boxed::Box;
<syntaxhighlight lang="rust">use std::boxed::Box;
use std::collections::{HashMap, HashSet};
use std::collections::{HashMap, HashSet};


Line 5,621: Line 5,621:
}
}
}
}
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 5,648: Line 5,648:
=={{header|Scheme}}==
=={{header|Scheme}}==
{{trans|Python}}
{{trans|Python}}
<lang scheme>
<syntaxhighlight lang="scheme">
(import (chezscheme))
(import (chezscheme))
(import (srfi srfi-1))
(import (srfi srfi-1))
Line 5,734: Line 5,734:
(newline)
(newline)
(write (topological-sort unsortable))
(write (topological-sort unsortable))
</syntaxhighlight>
</lang>


=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Perl}}
{{trans|Perl}}
<lang ruby>func print_topo_sort (deps) {
<syntaxhighlight lang="ruby">func print_topo_sort (deps) {
var ba = Hash.new;
var ba = Hash.new;
deps.each { |before, afters|
deps.each { |before, afters|
Line 5,779: Line 5,779:
print_topo_sort(deps);
print_topo_sort(deps);
deps{:dw01}.append('dw04'); # Add unresolvable dependency
deps{:dw01}.append('dw04'); # Add unresolvable dependency
print_topo_sort(deps);</lang>
print_topo_sort(deps);</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,797: Line 5,797:
{{trans|Rust}}
{{trans|Rust}}


<lang swift>let libs = [
<syntaxhighlight lang="swift">let libs = [
("des_system_lib", ["std", "synopsys", "std_cell_lib", "des_system_lib", "dw02", "dw01", "ramlib", "ieee"]),
("des_system_lib", ["std", "synopsys", "std_cell_lib", "des_system_lib", "dw02", "dw01", "ramlib", "ieee"]),
("dw01", ["ieee", "dw01", "dware", "gtech"]),
("dw01", ["ieee", "dw01", "dware", "gtech"]),
Line 5,865: Line 5,865:
}
}


print(topologicalSort(libs: buildLibraries(libs))!)</lang>
print(topologicalSort(libs: buildLibraries(libs))!)</syntaxhighlight>


{{out}}
{{out}}
Line 5,872: Line 5,872:


=={{header|Tailspin}}==
=={{header|Tailspin}}==
<lang tailspin>
<syntaxhighlight lang="tailspin">
data node <'.+'>, from <node>, to <node>
data node <'.+'>, from <node>, to <node>


Line 5,917: Line 5,917:
synopsys
synopsys
' -> lines -> collectDeps -> topologicalSort -> !OUT::write
' -> lines -> collectDeps -> topologicalSort -> !OUT::write
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 5,926: Line 5,926:
=={{header|Tcl}}==
=={{header|Tcl}}==
{{works with|Tcl|8.5}}
{{works with|Tcl|8.5}}
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5
proc topsort {data} {
proc topsort {data} {
# Clean the data
# Clean the data
Line 5,962: Line 5,962:
}
}
}
}
}</lang>
}</syntaxhighlight>
Demonstration code (which parses it from the format that the puzzle was posed in):
Demonstration code (which parses it from the format that the puzzle was posed in):
<lang tcl>set inputData {
<syntaxhighlight lang="tcl">set inputData {
des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
dw01 ieee dw01 dware gtech
dw01 ieee dw01 dware gtech
Line 5,983: Line 5,983:
dict set parsedData [lindex $line 0] [lrange $line 1 end]
dict set parsedData [lindex $line 0] [lrange $line 1 end]
}
}
puts [topsort $parsedData]</lang>
puts [topsort $parsedData]</syntaxhighlight>
Sample output:
Sample output:
<pre>ieee std synopsys dware gtech ramlib std_cell_lib dw01 dw02 dw05 dw06 dw07 des_system_lib dw03 dw04</pre>
<pre>ieee std synopsys dware gtech ramlib std_cell_lib dw01 dw02 dw05 dw06 dw07 des_system_lib dw03 dw04</pre>
Line 5,995: Line 5,995:


{{works with|Bourne Shell}}
{{works with|Bourne Shell}}
<lang bash>$ awk '{ for (i = 1; i <= NF; i++) print $i, $1 }' <<! | tsort
<syntaxhighlight lang="bash">$ awk '{ for (i = 1; i <= NF; i++) print $i, $1 }' <<! | tsort
> des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
> des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
> dw01 ieee dw01 dware gtech
> dw01 ieee dw01 dware gtech
Line 6,024: Line 6,024:
dw03
dw03
ramlib
ramlib
des_system_lib</lang>
des_system_lib</syntaxhighlight>


If the graph of dependencies contains a cycle, [[BSD]]'s tsort(1) will print messages to standard error, break the cycle (by deleting one of the dependencies), continue the sort, and exit 0. So if dw04 becomes a dependency of dw01, then tsort(1) finds the cycle between dw01 and dw04.
If the graph of dependencies contains a cycle, [[BSD]]'s tsort(1) will print messages to standard error, break the cycle (by deleting one of the dependencies), continue the sort, and exit 0. So if dw04 becomes a dependency of dw01, then tsort(1) finds the cycle between dw01 and dw04.
Line 6,053: Line 6,053:
unorderable libraries, if any, on the right. Self-dependences are
unorderable libraries, if any, on the right. Self-dependences are
ignored and unlisted libraries are presumed independent.
ignored and unlisted libraries are presumed independent.
<lang Ursala>tsort = ~&nmnNCjA*imSLs2nSjiNCSPT; @NiX ^=lxPrnSPX ^(~&rlPlT,~&rnPrmPljA*D@r)^|/~& ~&m!=rnSPlX</lang>
<syntaxhighlight lang="ursala">tsort = ~&nmnNCjA*imSLs2nSjiNCSPT; @NiX ^=lxPrnSPX ^(~&rlPlT,~&rnPrmPljA*D@r)^|/~& ~&m!=rnSPlX</syntaxhighlight>
test program:
test program:
<lang Ursala>#import std
<syntaxhighlight lang="ursala">#import std
dependence_table = -[
dependence_table = -[
Line 6,079: Line 6,079:
#show+
#show+


main = <.~&l,@r ~&i&& 'unorderable: '--> mat` ~~ tsort parse dependence_table</lang>
main = <.~&l,@r ~&i&& 'unorderable: '--> mat` ~~ tsort parse dependence_table</syntaxhighlight>
With the given table, the output is
With the given table, the output is
<pre>
<pre>
Line 6,092: Line 6,092:
=={{header|VBScript}}==
=={{header|VBScript}}==
=====Implementation=====
=====Implementation=====
<syntaxhighlight lang="vb">
<lang vb>
class topological
class topological
dim dictDependencies
dim dictDependencies
Line 6,172: Line 6,172:
end property
end property
end class
end class
</syntaxhighlight>
</lang>


=====Invocation=====
=====Invocation=====
<syntaxhighlight lang="vb">
<lang vb>
dim toposort
dim toposort
set toposort = new topological
set toposort = new topological
Line 6,199: Line 6,199:
toposort.reset
toposort.reset
next
next
</syntaxhighlight>
</lang>


=====Output=====
=====Output=====
Line 6,282: Line 6,282:
=={{header|Visual Basic .NET}}==
=={{header|Visual Basic .NET}}==
Adapted from http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html which was itself an adaptation of Java code. I added the Rosetta code specific format of dependencies, as well as checks for references to self.
Adapted from http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html which was itself an adaptation of Java code. I added the Rosetta code specific format of dependencies, as well as checks for references to self.
<lang vbnet>' Adapted from:
<syntaxhighlight lang="vbnet">' Adapted from:
' http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html
' http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html
' added/changed:
' added/changed:
Line 6,611: Line 6,611:
#End Region
#End Region
End Class
End Class
</syntaxhighlight>
</lang>
=====Output=====
=====Output=====
<pre>
<pre>
Line 6,695: Line 6,695:
=={{header|Wren}}==
=={{header|Wren}}==
{{trans|Kotlin}}
{{trans|Kotlin}}
<lang ecmascript>class Graph {
<syntaxhighlight lang="ecmascript">class Graph {
construct new(s, edges) {
construct new(s, edges) {
_vertices = s.split(", ")
_vertices = s.split(", ")
Line 6,760: Line 6,760:
var g2 = Graph.new(s, deps)
var g2 = Graph.new(s, deps)
System.print("Following the addition of dw04 to the dependencies of dw01:")
System.print("Following the addition of dw04 to the dependencies of dw01:")
System.print(g2.topoSort())</lang>
System.print(g2.topoSort())</syntaxhighlight>


{{out}}
{{out}}
Line 6,774: Line 6,774:
{{trans|Wikipedia}}
{{trans|Wikipedia}}
Input data is munged
Input data is munged
<lang zkl>fcn topoSort(data){ // data is L( L(root,L(leaves)),...)
<syntaxhighlight lang="zkl">fcn topoSort(data){ // data is L( L(root,L(leaves)),...)
allDs:=data.pump(List,fcn(rds){ T(Void.Write,Void.Write,rds[1]) }).copy();
allDs:=data.pump(List,fcn(rds){ T(Void.Write,Void.Write,rds[1]) }).copy();
roots:=Dictionary(data); // dictionary of root:leaves
roots:=Dictionary(data); // dictionary of root:leaves
Line 6,788: Line 6,788:
if(roots) throw(Exception.ValueError("Cycle: "+roots.keys));
if(roots) throw(Exception.ValueError("Cycle: "+roots.keys));
L
L
}</lang>
}</syntaxhighlight>
<lang zkl>data:=T(
<syntaxhighlight lang="zkl">data:=T(
"des_system_lib", "std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee",
"des_system_lib", "std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee",
"dw01", "ieee dw01 dware gtech",
"dw01", "ieee dw01 dware gtech",
Line 6,807: Line 6,807:
T( r, ds.replace(r,"").strip().split().copy() ) // leaves writable 'cause they will be
T( r, ds.replace(r,"").strip().split().copy() ) // leaves writable 'cause they will be
});
});
topoSort(data).println();</lang>
topoSort(data).println();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>