Browse Source

Getting cost of travel. What next?

Piotr Czajkowski 1 year ago
parent
commit
84bc64801e
1 changed files with 82 additions and 4 deletions
  1. 82 4
      16/code.go

+ 82 - 4
16/code.go

@@ -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)
 }