95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
package day09
|
|
|
|
import (
|
|
"aoc2015/aoclib"
|
|
"math"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func getDistanceMap(input []string) ([]string, map[string]map[string]int) {
|
|
distances := make(map[string]map[string]int)
|
|
var retCities []string
|
|
|
|
for _, line := range input {
|
|
distDescr := strings.Split(line, " = ")
|
|
cities := strings.Split(distDescr[0], " to ")
|
|
distance, _ := strconv.Atoi(distDescr[1])
|
|
|
|
if _, ok := distances[cities[0]]; !ok {
|
|
distances[cities[0]] = make(map[string]int)
|
|
retCities = append(retCities, cities[0])
|
|
}
|
|
distances[cities[0]][cities[1]] = distance
|
|
if _, ok := distances[cities[1]]; !ok {
|
|
distances[cities[1]] = make(map[string]int)
|
|
retCities = append(retCities, cities[1])
|
|
}
|
|
distances[cities[1]][cities[0]] = distance
|
|
}
|
|
|
|
return retCities, distances
|
|
}
|
|
|
|
func cityPermutations(slice []string) (permutations [][]string) {
|
|
if len(slice) == 1 {
|
|
return [][]string{slice}
|
|
} else if len(slice) == 2 {
|
|
return [][]string{
|
|
{
|
|
slice[0],
|
|
slice[1],
|
|
},
|
|
{
|
|
slice[1],
|
|
slice[0],
|
|
},
|
|
}
|
|
} else {
|
|
for i := range slice {
|
|
newSlice := make([]string, i)
|
|
copy(newSlice, slice[:i])
|
|
newSlice = append(newSlice, slice[i+1:]...)
|
|
subPermutations := cityPermutations(newSlice)
|
|
for _, subPermutation := range subPermutations {
|
|
permutations = append(permutations, append([]string{slice[i]}, subPermutation...))
|
|
}
|
|
}
|
|
return permutations
|
|
}
|
|
}
|
|
|
|
func getMinMaxDistances(permutations [][]string, distances map[string]map[string]int) (int, int) {
|
|
minDistance := math.MaxInt32
|
|
maxDistance := 0
|
|
|
|
for _, v := range permutations {
|
|
thisDistance := 0
|
|
for i := 0; i < len(v)-1; i++ {
|
|
thisDistance += distances[v[i]][v[i+1]]
|
|
}
|
|
if thisDistance < minDistance {
|
|
minDistance = thisDistance
|
|
}
|
|
if thisDistance > maxDistance {
|
|
maxDistance = thisDistance
|
|
}
|
|
}
|
|
|
|
return minDistance, maxDistance
|
|
}
|
|
|
|
func Part1(puzzle aoclib.Puzzle) interface{} {
|
|
cities, distances := getDistanceMap(puzzle.GetInputArray())
|
|
minDistance, _ := getMinMaxDistances(cityPermutations(cities), distances)
|
|
|
|
return minDistance
|
|
}
|
|
|
|
func Part2(puzzle aoclib.Puzzle) interface{} {
|
|
cities, distances := getDistanceMap(puzzle.GetInputArray())
|
|
_, maxDistance := getMinMaxDistances(cityPermutations(cities), distances)
|
|
|
|
return maxDistance
|
|
}
|