-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay25.kt
80 lines (67 loc) · 2.45 KB
/
Day25.kt
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
private fun findPath(
wires: Map<String, Collection<String>>,
current: String,
end: String,
visitedEdges: MutableList<String> = mutableListOf(),
visitedVertices: MutableSet<String> = mutableSetOf(),
): Boolean {
if (current in visitedVertices) return false
visitedVertices += current
visitedEdges += current
if (current == end) return true
wires[current]?.forEach {
if (findPath(wires, it, end, visitedEdges, visitedVertices)) return true
}
visitedEdges.removeLast()
return false
}
private fun traverse(wires: Map<String, Collection<String>>, current: String, visited: MutableSet<String>) {
if (current in visited) return
visited += current
wires[current]?.forEach { traverse(wires, it, visited) }
}
private fun findThreeBridges(wires: Map<String, Set<String>>): Int {
val sameComponent = mutableSetOf<Pair<String, String>>()
wires.keys.forEachIndexed { i, start ->
wires.keys.asSequence().take(i).forEachIndexed { j, end ->
val currentWires = wires.mapValues { it.value.toMutableSet() }.toMutableMap()
repeat(3) {
val visitedEdges = mutableListOf<String>()
findPath(currentWires, start, end, visitedEdges)
visitedEdges.asSequence().zipWithNext().forEach { (f, t) ->
currentWires[f]!! -= t
currentWires[t]!! -= f
}
}
if (findPath(currentWires, start, end)) sameComponent += start to end
}
}
val components = buildMap<String, MutableList<String>> {
sameComponent.forEach { (f, t) ->
getOrPut(f) { mutableListOf() } += t
getOrPut(t) { mutableListOf() } += f
}
}
val visited = mutableSetOf<String>()
return components.keys.asSequence()
.map {
val prevSize = visited.size
traverse(components, it, visited)
visited.size - prevSize
}
.filter { it != 0 }
.toList()
.let { (a, b) -> a * b }
}
fun main() {
val wires: Map<String, Set<String>> = buildMap<String, MutableSet<String>> {
lines().forEach { line ->
val (left, rights) = line.split(": ")
rights.splitToSequence(' ').forEach { right ->
getOrPut(left) { mutableSetOf() } += right
getOrPut(right) { mutableSetOf() } += left
}
}
}
println(findThreeBridges(wires))
}