167 lines
3.3 KiB
Go
167 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var allTowns map[string]roads
|
|
|
|
type roads map[string]int
|
|
|
|
func main() {
|
|
allTowns = make(map[string]roads)
|
|
var input []string
|
|
var readInp, bldInput string
|
|
for {
|
|
_, err := fmt.Scan(&readInp)
|
|
if err != nil {
|
|
if err != io.EOF {
|
|
log.Fatal(err)
|
|
}
|
|
break
|
|
}
|
|
|
|
if strings.HasSuffix(bldInput, "=") {
|
|
bldInput = bldInput + " " + readInp
|
|
input = append(input, bldInput)
|
|
bldInput = ""
|
|
continue
|
|
}
|
|
if len(bldInput) > 0 {
|
|
bldInput += " "
|
|
}
|
|
bldInput = bldInput + readInp
|
|
}
|
|
|
|
for i := range input {
|
|
dirTowns := strings.Split(input[i], " to ")
|
|
secondPart := strings.Split(dirTowns[1], " = ")
|
|
town1 := dirTowns[0]
|
|
town2 := secondPart[0]
|
|
distance := mustAtoi(secondPart[1])
|
|
buildRoute(town1, town2, distance)
|
|
}
|
|
|
|
// All routes should be built, find the shortest
|
|
var shortestRoute []string
|
|
shortestDistance := -1
|
|
for i := range allTowns {
|
|
var visited []string
|
|
lastVisit := i
|
|
tripDistance := 0
|
|
for len(visited) < len(allTowns) {
|
|
var dist int
|
|
visited = append(visited, lastVisit)
|
|
lastVisit, dist = findShortest(lastVisit, visited)
|
|
if dist > 0 {
|
|
tripDistance += dist
|
|
}
|
|
}
|
|
if shortestDistance == -1 || tripDistance < shortestDistance {
|
|
shortestDistance = tripDistance
|
|
shortestRoute = visited
|
|
}
|
|
}
|
|
|
|
// Now find the longest
|
|
var longestRoute []string
|
|
longestDistance := -1
|
|
for i := range allTowns {
|
|
var visited []string
|
|
lastVisit := i
|
|
tripDistance := 0
|
|
for len(visited) < len(allTowns) {
|
|
var dist int
|
|
visited = append(visited, lastVisit)
|
|
lastVisit, dist = findLongest(lastVisit, visited)
|
|
if dist > 0 {
|
|
tripDistance += dist
|
|
}
|
|
}
|
|
if longestDistance == -1 || tripDistance > longestDistance {
|
|
longestDistance = tripDistance
|
|
longestRoute = visited
|
|
}
|
|
}
|
|
|
|
fmt.Println("Shortest Route:" + strconv.Itoa(shortestDistance))
|
|
fmt.Println(strings.Join(shortestRoute, "->"))
|
|
fmt.Println("Longest Route:" + strconv.Itoa(longestDistance))
|
|
fmt.Println(strings.Join(longestRoute, "->"))
|
|
}
|
|
|
|
func findShortest(from string, exclude []string) (string, int) {
|
|
var toTown string
|
|
shortest := -1
|
|
for j := range allTowns[from] {
|
|
var didIt bool
|
|
for ex := range exclude {
|
|
if j == exclude[ex] {
|
|
didIt = true
|
|
break
|
|
}
|
|
}
|
|
if didIt {
|
|
continue
|
|
}
|
|
// Find the quickest trip from here
|
|
if shortest == -1 || allTowns[from][j] < shortest {
|
|
shortest = allTowns[from][j]
|
|
toTown = j
|
|
}
|
|
}
|
|
return toTown, shortest
|
|
}
|
|
|
|
func findLongest(from string, exclude []string) (string, int) {
|
|
var toTown string
|
|
longest := -1
|
|
for j := range allTowns[from] {
|
|
var didIt bool
|
|
for ex := range exclude {
|
|
if j == exclude[ex] {
|
|
didIt = true
|
|
break
|
|
}
|
|
}
|
|
if didIt {
|
|
continue
|
|
}
|
|
// Find the longest trip from here
|
|
if longest == -1 || allTowns[from][j] > longest {
|
|
longest = allTowns[from][j]
|
|
toTown = j
|
|
}
|
|
}
|
|
return toTown, longest
|
|
}
|
|
|
|
func mustAtoi(i string) int {
|
|
var ret int
|
|
var err error
|
|
if ret, err = strconv.Atoi(i); err != nil {
|
|
fmt.Println("Tried to mustAtoi: " + i)
|
|
os.Exit(1)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func buildRoute(t1, t2 string, dist int) {
|
|
if _, ok := allTowns[t1]; !ok {
|
|
// Add this town
|
|
allTowns[t1] = make(map[string]int)
|
|
}
|
|
allTowns[t1][t2] = dist
|
|
// And the other direction
|
|
if _, ok := allTowns[t2]; !ok {
|
|
// Add this town
|
|
allTowns[t2] = make(map[string]int)
|
|
}
|
|
allTowns[t2][t1] = dist
|
|
}
|