-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
130 lines (114 loc) · 2.59 KB
/
main.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"bufio"
"io"
"math"
aoc "github.com/teivah/advent-of-code"
)
func fs1(input io.Reader) int {
scanner := bufio.NewScanner(input)
graph := make(map[string]map[string]bool)
set := make(map[string]struct{})
for scanner.Scan() {
line := scanner.Text()
from, tos := parse(line)
set[from] = struct{}{}
for _, to := range tos {
add(graph, from, to)
add(graph, to, from)
set[to] = struct{}{}
}
}
distances := make(map[string]int)
minDistance := math.MaxInt
i := 0
for node := range set {
i++
visited := make(map[string]int)
dfs(graph, node, visited, 0)
best := 0
for _, d := range visited {
best = max(best, d)
}
distances[node] = best
minDistance = min(minDistance, best)
}
// Not sure if my solution is generic enough but in a nutshell, my intuition
// is that we can be found the nodes where we have to cut an edge by
// calculating the max distance to another node in the graph. Indeed, if
// if a node has a minimal max distance, then it means it's "in the middle" of
// the graph.
found := make(map[string]struct{})
for node, distance := range distances {
if distance == minDistance {
found[node] = struct{}{}
}
}
if len(found) != 6 {
panic("no result found")
}
var length [][2]string
deleted := make(map[string]bool)
for len(found) != 0 {
for from := range found {
delete(found, from)
for to := range found {
if _, exists := graph[from][to]; exists {
length = append(length, [2]string{from, to})
graph[from][to] = false
graph[to][from] = false
deleted[from] = true
deleted[to] = true
}
}
}
}
v1 := 0
for k := range set {
if deleted[k] {
continue
}
visited := make(map[string]int)
_ = dfs(graph, k, visited, 0)
v := len(visited)
if v1 == 0 {
v1 = v
} else {
if v != v1 {
return v1 * v
}
}
}
return 42
}
func dfs(graph map[string]map[string]bool, node string, visited map[string]int, distance int) int {
if v, contains := visited[node]; contains {
if v <= distance {
return 0
}
}
visited[node] = distance
tos := graph[node]
if len(tos) == 0 {
return distance
}
best := 0
for to, exists := range tos {
if !exists {
continue
}
best = max(best, dfs(graph, to, visited, distance+1))
}
return best
}
func add(graph map[string]map[string]bool, from, to string) {
if _, exists := graph[from]; !exists {
graph[from] = make(map[string]bool)
}
graph[from][to] = true
}
func parse(s string) (string, []string) {
del := aoc.NewDelimiter(s, ": ")
from := del.GetString(0)
return from, aoc.NewDelimiter(del.GetString(1), " ").GetStrings()
}