-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
120 lines (104 loc) · 2.63 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
package main
import (
"fmt"
"io/ioutil"
"strings"
)
type planet struct {
name string
orbiters []planet
depth int
}
func main() {
orbits := loadOrbits()
orbitMap := make(map[string][]string)
for i := 0; i < len(orbits); i++ {
if orbitMap[orbits[i][0]] == nil {
orbitMap[orbits[i][0]] = []string{orbits[i][1]}
} else {
orbitMap[orbits[i][0]] = append(orbitMap[orbits[i][0]], orbits[i][1])
}
}
sum := 0
root := findOrbiters("COM", orbitMap, 1, &sum)
fmt.Println("step1 --->", sum)
// find orbiter of YOU, keep the full chain
pathToYou := make(map[string]int)
findPathTo(root, "YOU", pathToYou)
youKeys := mapKeys(pathToYou)
// find orbiter of SAN, keep the full chain
pathToSan := make(map[string]int)
findPathTo(root, "SAN", pathToSan)
sanKeys := mapKeys(pathToSan)
// Find a common node between the two
commonMax := 0
for _, key := range youKeys {
if pathToSan[key] != 0 {
if pathToSan[key] > commonMax {
commonMax = pathToSan[key]
}
}
}
// find max value of YOU
youMax := 0
for _, key := range youKeys {
if pathToYou[key] > youMax {
youMax = pathToYou[key]
}
}
// find max value of SAN
sanMax := 0
for _, key := range sanKeys {
if pathToSan[key] > sanMax {
sanMax = pathToSan[key]
}
}
// add distance from SAN minus distance of common node + YOU and distance of common node
fmt.Println("step2 --->", sanMax-commonMax+youMax-commonMax)
}
func mapKeys(aMap map[string]int) []string {
sanKeys := make([]string, 0, len(aMap))
for key := range aMap {
sanKeys = append(sanKeys, key)
}
return sanKeys
}
func findPathTo(root planet, target string, path map[string]int) bool {
if root.name == target {
return true
}
for _, orbiter := range root.orbiters {
if findPathTo(orbiter, target, path) {
if orbiter.name != target {
path[orbiter.name] = orbiter.depth
}
return true
}
}
return false
}
func findOrbiters(rootName string, orbitMap map[string][]string, depth int, sum *int) planet {
rootPlanet := planet{rootName, []planet{}, depth}
for _, orbiter := range orbitMap[rootName] {
*sum += depth
rootPlanet.orbiters = append(rootPlanet.orbiters, findOrbiters(orbiter, orbitMap, depth+1, sum))
}
return rootPlanet
}
func loadOrbits() [][]string {
//rawListOfOrbits := load("orbit-test.txt")
rawListOfOrbits := load("orbit.txt")
orbits := [][]string{}
for _, orbitAsString := range strings.Split(rawListOfOrbits, "\n") {
orbit := strings.Split(string(orbitAsString), ")")
orbits = append(orbits, orbit)
}
return orbits
}
func load(filename string) string {
text, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Print(err)
}
return string(text)
}