-
Notifications
You must be signed in to change notification settings - Fork 2
/
inheritance.go
115 lines (99 loc) · 2.18 KB
/
inheritance.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package caskin
import (
"encoding/json"
"sort"
"github.com/ahmetb/go-linq/v3"
"golang.org/x/exp/constraints"
"golang.org/x/exp/slices"
)
// InheritanceEdge x is node, y is adjacency
type InheritanceEdge[T constraints.Ordered] struct {
U T `json:"u"`
V T `json:"v"`
}
func (i *InheritanceEdge[T]) Encode(u, v T) string {
i.U, i.V = u, v
b, _ := json.Marshal(i)
return string(b)
}
func (i *InheritanceEdge[T]) Decode(in string) error {
return json.Unmarshal([]byte(in), i)
}
type EdgeSorter[T constraints.Ordered] map[T]int
func (e EdgeSorter[T]) RootFirstSort(edges []*InheritanceEdge[T]) {
sort.Slice(edges, func(i, j int) bool {
return e[edges[i].U] < e[edges[j].U]
})
}
func (e EdgeSorter[T]) LeafFirstSort(edges []*InheritanceEdge[T]) {
sort.Slice(edges, func(i, j int) bool {
return e[edges[i].V] > e[edges[j].V]
})
}
func NewEdgeSorter[T constraints.Ordered](order []T) EdgeSorter[T] {
sorter := map[T]int{}
for i, v := range order {
sorter[v] = i
}
return sorter
}
type InheritanceGraph[T constraints.Ordered] map[T][]T
func (g InheritanceGraph[T]) Sort() InheritanceGraph[T] {
var keys []T
for k := range g {
keys = append(keys, k)
}
slices.Sort(keys)
m := InheritanceGraph[T]{}
for _, k := range keys {
m[k] = g[k]
slices.Sort(m[k])
}
return m
}
func (g InheritanceGraph[T]) TopSort() []T {
inDegree := map[T]int{}
for k := range g {
inDegree[k] = 0
}
for _, node := range g {
for _, v := range node {
inDegree[v]++
}
}
var queue []T
for k, v := range inDegree {
if v == 0 {
queue = append(queue, k)
}
}
for i := 0; i < len(queue); i++ {
node := queue[i]
for _, v := range g[node] {
inDegree[v]--
if inDegree[v] == 0 {
queue = append(queue, v)
}
}
}
return queue
}
func MergeInheritanceGraph[T constraints.Ordered](graphs ...InheritanceGraph[T]) InheritanceGraph[T] {
m := InheritanceGraph[T]{}
for _, graph := range graphs {
for node, adjacency := range graph {
if _, ok := m[node]; !ok {
m[node] = []T{}
}
for _, v := range adjacency {
m[node] = append(m[node], v)
}
}
}
for node, adjacency := range m {
var t []T
linq.From(adjacency).Distinct().ToSlice(&t)
m[node] = t
}
return m.Sort()
}