diff --git a/day09/day09.go b/day09/day09.go new file mode 100644 index 0000000..51b7ef0 --- /dev/null +++ b/day09/day09.go @@ -0,0 +1,94 @@ +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 +} diff --git a/inputs/9 b/inputs/9 new file mode 100644 index 0000000..df5432f --- /dev/null +++ b/inputs/9 @@ -0,0 +1,28 @@ +Faerun to Tristram = 65 +Faerun to Tambi = 129 +Faerun to Norrath = 144 +Faerun to Snowdin = 71 +Faerun to Straylight = 137 +Faerun to AlphaCentauri = 3 +Faerun to Arbre = 149 +Tristram to Tambi = 63 +Tristram to Norrath = 4 +Tristram to Snowdin = 105 +Tristram to Straylight = 125 +Tristram to AlphaCentauri = 55 +Tristram to Arbre = 14 +Tambi to Norrath = 68 +Tambi to Snowdin = 52 +Tambi to Straylight = 65 +Tambi to AlphaCentauri = 22 +Tambi to Arbre = 143 +Norrath to Snowdin = 8 +Norrath to Straylight = 23 +Norrath to AlphaCentauri = 136 +Norrath to Arbre = 115 +Snowdin to Straylight = 101 +Snowdin to AlphaCentauri = 84 +Snowdin to Arbre = 96 +Straylight to AlphaCentauri = 107 +Straylight to Arbre = 14 +AlphaCentauri to Arbre = 46 \ No newline at end of file diff --git a/inputs/9_test b/inputs/9_test new file mode 100644 index 0000000..d8224f9 --- /dev/null +++ b/inputs/9_test @@ -0,0 +1,3 @@ +London to Dublin = 464 +London to Belfast = 518 +Dublin to Belfast = 141 \ No newline at end of file diff --git a/main.go b/main.go index 603955d..1764c2d 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "aoc2015/day06" "aoc2015/day07" "aoc2015/day08" + "aoc2015/day09" "flag" "fmt" "os" @@ -25,31 +26,34 @@ var timeitNumber int var myDir, _ = filepath.Abs(filepath.Dir(os.Args[0])) func initDayFunctions() { - dayFunctions = make(map[int]map[int]func(puzzle aoclib.Puzzle) interface{}) - dayFunctions[1] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions = make(map[int]map[int]func(puzzle aoclib.Puzzle) interface{}, 25) + dayFunctions[1] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[1][1] = day01.Part1 dayFunctions[1][2] = day01.Part2 - dayFunctions[2] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[2] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[2][1] = day02.Part1 dayFunctions[2][2] = day02.Part2 - dayFunctions[3] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[3] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[3][1] = day03.Part1 dayFunctions[3][2] = day03.Part2 - dayFunctions[4] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[4] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[4][1] = day04.Part1 dayFunctions[4][2] = day04.Part2 - dayFunctions[5] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[5] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[5][1] = day05.Part1 dayFunctions[5][2] = day05.Part2 - dayFunctions[6] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[6] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[6][1] = day06.Part1 dayFunctions[6][2] = day06.Part2 - dayFunctions[7] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[7] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[7][1] = day07.Part1 dayFunctions[7][2] = day07.Part2 - dayFunctions[8] = make(map[int]func(puzzle aoclib.Puzzle) interface{}) + dayFunctions[8] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) dayFunctions[8][1] = day08.Part1 dayFunctions[8][2] = day08.Part2 + dayFunctions[9] = make(map[int]func(puzzle aoclib.Puzzle) interface{}, 2) + dayFunctions[9][1] = day09.Part1 + dayFunctions[9][2] = day09.Part2 } func execute(thisDay int) {