Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
140
Task/Topological-sort/Go/topological-sort-1.go
Normal file
140
Task/Topological-sort/Go/topological-sort-1.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var data = `
|
||||
LIBRARY LIBRARY DEPENDENCIES
|
||||
======= ====================
|
||||
des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
|
||||
dw01 ieee dw01 dware gtech
|
||||
dw02 ieee dw02 dware
|
||||
dw03 std synopsys dware dw03 dw02 dw01 ieee gtech
|
||||
dw04 dw04 ieee dw01 dware gtech
|
||||
dw05 dw05 ieee dware
|
||||
dw06 dw06 ieee dware
|
||||
dw07 ieee dware
|
||||
dware ieee dware
|
||||
gtech ieee gtech
|
||||
ramlib std ieee
|
||||
std_cell_lib ieee std_cell_lib
|
||||
synopsys `
|
||||
|
||||
func main() {
|
||||
g, in, err := parseLibComp(data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
order, cyclic := topSortKahn(g, in)
|
||||
if cyclic != nil {
|
||||
fmt.Println("Cyclic:", cyclic)
|
||||
return
|
||||
}
|
||||
fmt.Println("Order:", order)
|
||||
}
|
||||
|
||||
type graph map[string][]string
|
||||
type inDegree map[string]int
|
||||
|
||||
// parseLibComp parses the text format of the task and returns a graph
|
||||
// representation and a list of the in-degrees of each node. The returned graph
|
||||
// represents compile order rather than dependency order. That is, for each map
|
||||
// map key n, the map elements are libraries that depend on n being compiled
|
||||
// first.
|
||||
func parseLibComp(data string) (g graph, in inDegree, err error) {
|
||||
// small sanity check on input
|
||||
lines := strings.Split(data, "\n")
|
||||
if len(lines) < 3 || !strings.HasPrefix(lines[2], "=") {
|
||||
return nil, nil, fmt.Errorf("data format")
|
||||
}
|
||||
// toss header lines
|
||||
lines = lines[3:]
|
||||
// scan and interpret input, build graph
|
||||
g = graph{}
|
||||
in = inDegree{}
|
||||
for _, line := range lines {
|
||||
libs := strings.Fields(line)
|
||||
if len(libs) == 0 {
|
||||
continue // allow blank lines
|
||||
}
|
||||
lib := libs[0]
|
||||
g[lib] = g[lib]
|
||||
for _, dep := range libs[1:] {
|
||||
in[dep] = in[dep]
|
||||
if dep == lib {
|
||||
continue // ignore self dependencies
|
||||
}
|
||||
successors := g[dep]
|
||||
for i := 0; ; i++ {
|
||||
if i == len(successors) {
|
||||
g[dep] = append(successors, lib)
|
||||
in[lib]++
|
||||
break
|
||||
}
|
||||
if dep == successors[i] {
|
||||
break // ignore duplicate dependencies
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return g, in, nil
|
||||
}
|
||||
|
||||
// General purpose topological sort, not specific to the application of
|
||||
// library dependencies. Adapted from Wikipedia pseudo code, one main
|
||||
// difference here is that this function does not consume the input graph.
|
||||
// WP refers to incoming edges, but does not really need them fully represented.
|
||||
// A count of incoming edges, or the in-degree of each node is enough. Also,
|
||||
// WP stops at cycle detection and doesn't output information about the cycle.
|
||||
// A little extra code at the end of this function recovers the cyclic nodes.
|
||||
func topSortKahn(g graph, in inDegree) (order, cyclic []string) {
|
||||
var L, S []string
|
||||
// rem for "remaining edges," this function makes a local copy of the
|
||||
// in-degrees and consumes that instead of consuming an input.
|
||||
rem := inDegree{}
|
||||
for n, d := range in {
|
||||
if d == 0 {
|
||||
// accumulate "set of all nodes with no incoming edges"
|
||||
S = append(S, n)
|
||||
} else {
|
||||
// initialize rem from in-degree
|
||||
rem[n] = d
|
||||
}
|
||||
}
|
||||
for len(S) > 0 {
|
||||
last := len(S) - 1 // "remove a node n from S"
|
||||
n := S[last]
|
||||
S = S[:last]
|
||||
L = append(L, n) // "add n to tail of L"
|
||||
for _, m := range g[n] {
|
||||
// WP pseudo code reads "for each node m..." but it means for each
|
||||
// node m *remaining in the graph.* We consume rem rather than
|
||||
// the graph, so "remaining in the graph" for us means rem[m] > 0.
|
||||
if rem[m] > 0 {
|
||||
rem[m]-- // "remove edge from the graph"
|
||||
if rem[m] == 0 { // if "m has no other incoming edges"
|
||||
S = append(S, m) // "insert m into S"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// "If graph has edges," for us means a value in rem is > 0.
|
||||
for c, in := range rem {
|
||||
if in > 0 {
|
||||
// recover cyclic nodes
|
||||
for _, nb := range g[c] {
|
||||
if rem[nb] > 0 {
|
||||
cyclic = append(cyclic, c)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(cyclic) > 0 {
|
||||
return nil, cyclic
|
||||
}
|
||||
return L, nil
|
||||
}
|
||||
48
Task/Topological-sort/Go/topological-sort-2.go
Normal file
48
Task/Topological-sort/Go/topological-sort-2.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// General purpose topological sort, not specific to the application of
|
||||
// library dependencies. Also adapted from Wikipedia pseudo code.
|
||||
func topSortDFS(g graph) (order, cyclic []string) {
|
||||
L := make([]string, len(g))
|
||||
i := len(L)
|
||||
temp := map[string]bool{}
|
||||
perm := map[string]bool{}
|
||||
var cycleFound bool
|
||||
var cycleStart string
|
||||
var visit func(string)
|
||||
visit = func(n string) {
|
||||
switch {
|
||||
case temp[n]:
|
||||
cycleFound = true
|
||||
cycleStart = n
|
||||
return
|
||||
case perm[n]:
|
||||
return
|
||||
}
|
||||
temp[n] = true
|
||||
for _, m := range g[n] {
|
||||
visit(m)
|
||||
if cycleFound {
|
||||
if cycleStart > "" {
|
||||
cyclic = append(cyclic, n)
|
||||
if n == cycleStart {
|
||||
cycleStart = ""
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
delete(temp, n)
|
||||
perm[n] = true
|
||||
i--
|
||||
L[i] = n
|
||||
}
|
||||
for n := range g {
|
||||
if perm[n] {
|
||||
continue
|
||||
}
|
||||
visit(n)
|
||||
if cycleFound {
|
||||
return nil, cyclic
|
||||
}
|
||||
}
|
||||
return L, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue