Topological sort: Difference between revisions
Content added Content deleted
m (→{{header|Object Pascal}}: changed highlighter from "Object Pascal" to pascal) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 56: | Line 56: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<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"))</ |
print(toposort2(&data).join("\n"))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 120: | Line 120: | ||
The specification: |
The specification: |
||
< |
<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;</ |
end Digraphs;</syntaxhighlight> |
||
The implementation: |
The implementation: |
||
< |
<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;</ |
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: |
||
< |
<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;</ |
end Set_Of_Names;</syntaxhighlight> |
||
The implementation |
The implementation |
||
< |
<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;</ |
end Set_Of_Names;</syntaxhighlight> |
||
'''Toposort: Putting things together for the main program''' |
'''Toposort: Putting things together for the main program''' |
||
< |
<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;</ |
end Toposort;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 496: | Line 496: | ||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
< |
<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) |
||
);</ |
);</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. |
||
< |
<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; |
||
}</ |
}</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</ |
4: des_system_lib dw03 dw04</syntaxhighlight> |
||
=={{header|C sharp}}== |
=={{header|C sharp}}== |
||
< |
<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...</ |
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...</ |
exiting...</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
===C++11=== |
===C++11=== |
||
< |
<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())); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===C++17=== |
===C++17=== |
||
< |
<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; |
||
}</ |
}</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</ |
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</ |
I - destroyed</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Line 1,192: | Line 1,192: | ||
=====Implementation===== |
=====Implementation===== |
||
< |
<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: |
||
< |
<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))</ |
(concat cyclic-dependence good-sample))</syntaxhighlight> |
||
====={{out}}===== |
====={{out}}===== |
||
< |
<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)"</ |
"ERROR: cycles remain among (:dw01 :dw04 :dw03 :des_system_lib)"</syntaxhighlight> |
||
=={{header|CoffeeScript}}== |
=={{header|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}}== |
||
< |
<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)))))))</ |
entries)))))))</syntaxhighlight> |
||
Provided example in which all items can be sorted: |
Provided example in which all items can be sorted: |
||
< |
<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</ |
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.) |
||
< |
<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)</ |
DES-SYSTEM-LIB (1)</syntaxhighlight> |
||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
< |
<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}} |
||
< |
<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; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>#1 : ["ieee", "std", "synopsys"] |
<pre>#1 : ["ieee", "std", "synopsys"] |
||
Line 1,674: | Line 1,674: | ||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<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 |
||
}</ |
}</syntaxhighlight> |
||
< |
<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))</ |
println(topoSort(data))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,754: | Line 1,754: | ||
''' Data |
''' Data |
||
< |
<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) |
||
< |
<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}} |
||
< |
<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}} |
||
< |
<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)</ |
Topological.sort(bad_libraries)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,895: | Line 1,895: | ||
=={{header|Erlang}}== |
=={{header|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}} |
||
< |
<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</ |
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}} |
||
< |
<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</ |
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). |
||
< |
<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</ |
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). |
||
< |
<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</ |
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). |
||
< |
<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}}== |
||
< |
<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 )</ |
Some( ordering ) -> println( ordering )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,322: | Line 2,322: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
===Kahn=== |
===Kahn=== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 2,461: | Line 2,461: | ||
} |
} |
||
return L, nil |
return L, nil |
||
}</ |
}</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. |
||
< |
<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 |
||
}</ |
}</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}}== |
||
< |
<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</ |
main = print $ toposort depLibs</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<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"]]</ |
*** Exception: Dependency cycle detected for libs [["dw01","dw04"]]</syntaxhighlight> |
||
=={{header|Huginn}}== |
=={{header|Huginn}}== |
||
< |
<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 ) ) ); |
||
}</ |
}</syntaxhighlight> |
||
==Icon and Unicon== |
==Icon and Unicon== |
||
Line 2,669: | Line 2,669: | ||
elements have been built. |
elements have been built. |
||
< |
<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</ |
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. |
||
< |
<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</ |
end</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
< |
<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 |
||
)</ |
)</syntaxhighlight> |
||
With the sample data set: |
With the sample data set: |
||
Line 2,929: | Line 2,929: | ||
We would get: |
We would get: |
||
< |
<syntaxhighlight lang="j"> >dependencySort dependencies |
||
std |
std |
||
ieee |
ieee |
||
Line 2,944: | Line 2,944: | ||
dw04 |
dw04 |
||
dw03 |
dw03 |
||
des_system_lib</ |
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: |
||
< |
<syntaxhighlight lang="j"> dependencySort dependencies,'dw01 dw04',LF |
||
|assertion failure: dependencySort |
|assertion failure: dependencySort |
||
| -.1 e.(<0 1)|:depends</ |
| -.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): |
||
< |
<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 |
||
)</ |
)</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}} |
||
< |
<syntaxhighlight lang="java">import java.util.*; |
||
public class TopologicalSort { |
public class TopologicalSort { |
||
Line 3,043: | Line 3,043: | ||
return false; |
return false; |
||
} |
} |
||
}</ |
}</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==== |
||
< |
<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); |
||
</ |
</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. |
||
< |
<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</ |
tsort</syntaxhighlight> |
||
Data: |
Data: |
||
< |
<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}} |
||
< |
<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 - "))</ |
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}} |
||
< |
<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()) |
||
}</ |
}</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> |
||
< |
<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}}== |
||
< |
<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. |
||
< |
<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", {}}}</ |
{"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}}== |
||
< |
<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()</ |
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. |
||
< |
<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}}== |
||
< |
<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); |
||
;;</ |
;;</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: |
||
< |
<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</ |
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. |
||
< |
<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);</ |
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. |
||
<!--< |
<!--<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> |
||
<!--</ |
<!--</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}}== |
||
< |
<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].</ |
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. |
||
< |
<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=[] |
||
].</ |
].</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,788: | Line 4,788: | ||
===Test with cycles=== |
===Test with cycles=== |
||
< |
<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] |
||
].</ |
].</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,830: | Line 4,830: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<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))) ) ) ) ) )</ |
(=: dep (delete @ (: dep))) ) ) ) ) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>: (sortDependencies |
<pre>: (sortDependencies |
||
Line 4,864: | Line 4,864: | ||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
< |
<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 |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<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()</ |
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=== |
||
< |
<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) ))</ |
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=== |
||
< |
<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()))</ |
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}}== |
||
< |
<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: |
||
< |
<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 |
<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);</ |
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 '''do''' loops (or '''do''' structures), and |
Some of the FORTRAN 77 statements were converted to '''do''' loops (or '''do''' structures), and |
||
<br>some variables were [https://en.wikipedia.org/wiki/Camel_case <u>''camel capitalized]''</u>. |
<br>some variables were [https://en.wikipedia.org/wiki/Camel_case <u>''camel capitalized]''</u>. |
||
< |
<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</ |
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. |
||
< |
<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</ |
synopsys</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,509: | Line 5,509: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<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}} |
||
< |
<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}} |
||
< |
<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);</ |
print_topo_sort(deps);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,797: | Line 5,797: | ||
{{trans|Rust}} |
{{trans|Rust}} |
||
< |
<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))!)</ |
print(topologicalSort(libs: buildLibraries(libs))!)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,872: | Line 5,872: | ||
=={{header|Tailspin}}== |
=={{header|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}} |
||
< |
<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: | ||
} |
} |
||
} |
} |
||
}</ |
}</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): |
||
< |
<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]</ |
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}} |
||
< |
<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</ |
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. |
||
< |
<syntaxhighlight lang="ursala">tsort = ~&nmnNCjA*imSLs2nSjiNCSPT; @NiX ^=lxPrnSPX ^(~&rlPlT,~&rnPrmPljA*D@r)^|/~& ~&m!=rnSPlX</syntaxhighlight> |
||
test program: |
test program: |
||
< |
<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</ |
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. |
||
< |
<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}} |
||
< |
<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())</ |
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 |
||
< |
<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 |
||
}</ |
}</syntaxhighlight> |
||
< |
<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();</ |
topoSort(data).println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |