|
@@ -16,10 +16,18 @@ type valve struct {
|
|
|
connections []string
|
|
|
}
|
|
|
|
|
|
-func readInput(file *os.File) ([]string, map[string]valve) {
|
|
|
+type vertex struct {
|
|
|
+ name string
|
|
|
+ cost int
|
|
|
+ visited bool
|
|
|
+}
|
|
|
+
|
|
|
+const maxValue int = 100000
|
|
|
+
|
|
|
+func readInput(file *os.File) ([]vertex, map[string]valve) {
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
valves := make(map[string]valve)
|
|
|
- var vertices []string
|
|
|
+ var vertices []vertex
|
|
|
|
|
|
for scanner.Scan() {
|
|
|
line := scanner.Text()
|
|
@@ -48,7 +56,7 @@ func readInput(file *os.File) ([]string, map[string]valve) {
|
|
|
current.connections = append(current.connections, connection)
|
|
|
}
|
|
|
|
|
|
- vertices = append(vertices, current.name)
|
|
|
+ vertices = append(vertices, vertex{current.name, maxValue, false})
|
|
|
valves[current.name] = current
|
|
|
}
|
|
|
|
|
@@ -72,6 +80,75 @@ func buildGraph(valves map[string]valve) []path {
|
|
|
return graph
|
|
|
}
|
|
|
|
|
|
+func setCost(name string, cost int, vertices []vertex) {
|
|
|
+ for i := range vertices {
|
|
|
+ if vertices[i].name == name {
|
|
|
+ vertices[i].cost = cost
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func getCost(name string, vertices []vertex) int {
|
|
|
+ for i := range vertices {
|
|
|
+ if vertices[i].name == name {
|
|
|
+ return vertices[i].cost
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func getNext(vertices []vertex, valves map[string]valve) *vertex {
|
|
|
+ min := maxValue
|
|
|
+ var current *vertex
|
|
|
+ for i := range vertices {
|
|
|
+ if vertices[i].visited {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if vertices[i].cost <= min {
|
|
|
+ min = vertices[i].cost
|
|
|
+ current = &vertices[i]
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return current
|
|
|
+}
|
|
|
+
|
|
|
+func traverse(vertices []vertex, graph []path, valves map[string]valve) {
|
|
|
+ current := &vertices[0]
|
|
|
+ current.cost = 0
|
|
|
+ for {
|
|
|
+ for j := range graph {
|
|
|
+ if graph[j].from != current.name {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ var tentativeCost int
|
|
|
+ if current.cost == maxValue {
|
|
|
+ tentativeCost = maxValue
|
|
|
+ } else {
|
|
|
+ tentativeCost = current.cost + graph[j].cost
|
|
|
+ }
|
|
|
+
|
|
|
+ if tentativeCost < getCost(graph[j].to, vertices) {
|
|
|
+ setCost(graph[j].to, tentativeCost, vertices)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ val, _ := valves[current.name]
|
|
|
+ val.open = true
|
|
|
+ valves[current.name] = val
|
|
|
+ current.visited = true
|
|
|
+
|
|
|
+ current = getNext(vertices, valves)
|
|
|
+ if current == nil {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func main() {
|
|
|
if len(os.Args) < 2 {
|
|
|
log.Fatal("You need to specify a file!")
|
|
@@ -86,5 +163,6 @@ func main() {
|
|
|
|
|
|
vertices, valves := readInput(file)
|
|
|
graph := buildGraph(valves)
|
|
|
- fmt.Println(vertices, graph)
|
|
|
+ traverse(vertices, graph, valves)
|
|
|
+ fmt.Println(vertices, valves)
|
|
|
}
|