1
+ package org.jetbrains.kotlin.utils
2
+
3
+ import java.util.*
4
+
5
+ // Copied from Kotlin org.jetbrains.kotlin.utils.DFS class
6
+ @Suppress(" MemberVisibilityCanBePrivate" , " MemberVisibilityCanBePrivate" , " unused" )
7
+ object DFS {
8
+ fun <N , R > dfs (nodes : Collection <N >, neighbors : Neighbors <N >, visited : Visited <N >, handler : NodeHandler <N , R >): R {
9
+ for (node in nodes) {
10
+ doDfs(node, neighbors, visited, handler)
11
+ }
12
+ return handler.result()
13
+ }
14
+
15
+ fun <N , R > dfs (
16
+ nodes : Collection <N >,
17
+ neighbors : Neighbors <N >,
18
+ handler : NodeHandler <N , R >
19
+ ): R {
20
+ return dfs(nodes, neighbors, VisitedWithSet (), handler)
21
+ }
22
+
23
+ fun <N > ifAny (
24
+ nodes : Collection <N >,
25
+ neighbors : Neighbors <N >,
26
+ predicate : Function1 <N , Boolean >
27
+ ): Boolean {
28
+ val result = BooleanArray (1 )
29
+ return dfs(nodes, neighbors, object : AbstractNodeHandler <N , Boolean ?>() {
30
+ override fun beforeChildren (current : N ): Boolean {
31
+ if (predicate.invoke(current)) {
32
+ result[0 ] = true
33
+ }
34
+ return ! result[0 ]
35
+ }
36
+
37
+ override fun result (): Boolean {
38
+ return result[0 ]
39
+ }
40
+ })!!
41
+ }
42
+
43
+ fun <N , R > dfsFromNode (node : N , neighbors : Neighbors <N >, visited : Visited <N >, handler : NodeHandler <N , R >): R {
44
+ doDfs(node, neighbors, visited, handler)
45
+ return handler.result()
46
+ }
47
+
48
+ fun <N > dfsFromNode (
49
+ node : N ,
50
+ neighbors : Neighbors <N >,
51
+ visited : Visited <N >
52
+ ) {
53
+ dfsFromNode(node, neighbors, visited, object : AbstractNodeHandler <N , Void ?>() {
54
+ override fun result (): Void ? {
55
+ return null
56
+ }
57
+ })
58
+ }
59
+
60
+ fun <N > topologicalOrder (nodes : Iterable <N >, neighbors : Neighbors <N >, visited : Visited <N >): List <N > {
61
+ val handler = TopologicalOrder <N >()
62
+ for (node in nodes) {
63
+ doDfs(node, neighbors, visited, handler)
64
+ }
65
+ return handler.result()
66
+ }
67
+
68
+ fun <N > topologicalOrder (nodes : Iterable <N >, neighbors : Neighbors <N >): List <N > {
69
+ return topologicalOrder(nodes, neighbors, VisitedWithSet ())
70
+ }
71
+
72
+ fun <N > doDfs (current : N , neighbors : Neighbors <N >, visited : Visited <N >, handler : NodeHandler <N , * >) {
73
+ if (! visited.checkAndMarkVisited(current)) return
74
+ if (! handler.beforeChildren(current)) return
75
+ for (neighbor in neighbors.getNeighbors(current)) {
76
+ doDfs(neighbor, neighbors, visited, handler)
77
+ }
78
+ handler.afterChildren(current)
79
+ }
80
+
81
+ interface NodeHandler <N , R > {
82
+ fun beforeChildren (current : N ): Boolean
83
+ fun afterChildren (current : N )
84
+ fun result (): R
85
+ }
86
+
87
+ interface Neighbors <N > {
88
+ fun getNeighbors (current : N ): Iterable <N >
89
+ }
90
+
91
+ interface Visited <N > {
92
+ fun checkAndMarkVisited (current : N ): Boolean
93
+ }
94
+
95
+ abstract class AbstractNodeHandler <N , R > : NodeHandler <N , R > {
96
+ override fun beforeChildren (current : N ): Boolean {
97
+ return true
98
+ }
99
+
100
+ override fun afterChildren (current : N ) {}
101
+ }
102
+
103
+ class VisitedWithSet <N > @JvmOverloads constructor(private val visited : MutableSet <N > = HashSet ()) : Visited<N> {
104
+ override fun checkAndMarkVisited (current : N ): Boolean {
105
+ return visited.add(current)
106
+ }
107
+ }
108
+
109
+ abstract class CollectingNodeHandler <N , R , C : Iterable <R >> protected constructor(protected val result : C ) : AbstractNodeHandler<N, C>() {
110
+ override fun result (): C {
111
+ return result
112
+ }
113
+ }
114
+
115
+ abstract class NodeHandlerWithListResult <N , R > protected constructor() : CollectingNodeHandler<N, R, LinkedList<R>>(LinkedList <R >())
116
+ class TopologicalOrder <N > : NodeHandlerWithListResult <N , N >() {
117
+ override fun afterChildren (current : N ) {
118
+ result.addFirst(current)
119
+ }
120
+ }
121
+ }
0 commit comments