From 752475eab53bbfe78d1551df1ed71ea332c95dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kleszczy=C5=84ski?= Date: Thu, 7 Nov 2024 22:41:05 +0100 Subject: [PATCH] Day 13 --- d09/main.go | 2 ++ d13/input.txt | 56 ++++++++++++++++++++++++++++++ d13/main.go | 79 +++++++++++++++++++++++++++++++++++++++++++ d13/test-runs/0.txt | 12 +++++++ util/array.go | 18 ++++++++++ util/combinatorics.go | 32 ++++++++++++++++++ 6 files changed, 199 insertions(+) create mode 100644 d13/input.txt create mode 100644 d13/main.go create mode 100644 d13/test-runs/0.txt diff --git a/d09/main.go b/d09/main.go index 38c35cf..428af7b 100644 --- a/d09/main.go +++ b/d09/main.go @@ -69,6 +69,8 @@ func calculateDistances(data []Route) []int { }) } +// https://pl.wikipedia.org/wiki/Problem_komiwoja%C5%BCera +// https://en.wikipedia.org/wiki/Travelling_salesman_problem func part1(data []Route) int { distances := calculateDistances(data) diff --git a/d13/input.txt b/d13/input.txt new file mode 100644 index 0000000..06f51d1 --- /dev/null +++ b/d13/input.txt @@ -0,0 +1,56 @@ +Alice would gain 54 happiness units by sitting next to Bob. +Alice would lose 81 happiness units by sitting next to Carol. +Alice would lose 42 happiness units by sitting next to David. +Alice would gain 89 happiness units by sitting next to Eric. +Alice would lose 89 happiness units by sitting next to Frank. +Alice would gain 97 happiness units by sitting next to George. +Alice would lose 94 happiness units by sitting next to Mallory. +Bob would gain 3 happiness units by sitting next to Alice. +Bob would lose 70 happiness units by sitting next to Carol. +Bob would lose 31 happiness units by sitting next to David. +Bob would gain 72 happiness units by sitting next to Eric. +Bob would lose 25 happiness units by sitting next to Frank. +Bob would lose 95 happiness units by sitting next to George. +Bob would gain 11 happiness units by sitting next to Mallory. +Carol would lose 83 happiness units by sitting next to Alice. +Carol would gain 8 happiness units by sitting next to Bob. +Carol would gain 35 happiness units by sitting next to David. +Carol would gain 10 happiness units by sitting next to Eric. +Carol would gain 61 happiness units by sitting next to Frank. +Carol would gain 10 happiness units by sitting next to George. +Carol would gain 29 happiness units by sitting next to Mallory. +David would gain 67 happiness units by sitting next to Alice. +David would gain 25 happiness units by sitting next to Bob. +David would gain 48 happiness units by sitting next to Carol. +David would lose 65 happiness units by sitting next to Eric. +David would gain 8 happiness units by sitting next to Frank. +David would gain 84 happiness units by sitting next to George. +David would gain 9 happiness units by sitting next to Mallory. +Eric would lose 51 happiness units by sitting next to Alice. +Eric would lose 39 happiness units by sitting next to Bob. +Eric would gain 84 happiness units by sitting next to Carol. +Eric would lose 98 happiness units by sitting next to David. +Eric would lose 20 happiness units by sitting next to Frank. +Eric would lose 6 happiness units by sitting next to George. +Eric would gain 60 happiness units by sitting next to Mallory. +Frank would gain 51 happiness units by sitting next to Alice. +Frank would gain 79 happiness units by sitting next to Bob. +Frank would gain 88 happiness units by sitting next to Carol. +Frank would gain 33 happiness units by sitting next to David. +Frank would gain 43 happiness units by sitting next to Eric. +Frank would gain 77 happiness units by sitting next to George. +Frank would lose 3 happiness units by sitting next to Mallory. +George would lose 14 happiness units by sitting next to Alice. +George would lose 12 happiness units by sitting next to Bob. +George would lose 52 happiness units by sitting next to Carol. +George would gain 14 happiness units by sitting next to David. +George would lose 62 happiness units by sitting next to Eric. +George would lose 18 happiness units by sitting next to Frank. +George would lose 17 happiness units by sitting next to Mallory. +Mallory would lose 36 happiness units by sitting next to Alice. +Mallory would gain 76 happiness units by sitting next to Bob. +Mallory would lose 34 happiness units by sitting next to Carol. +Mallory would gain 37 happiness units by sitting next to David. +Mallory would gain 40 happiness units by sitting next to Eric. +Mallory would gain 18 happiness units by sitting next to Frank. +Mallory would gain 7 happiness units by sitting next to George. \ No newline at end of file diff --git a/d13/main.go b/d13/main.go new file mode 100644 index 0000000..0152a18 --- /dev/null +++ b/d13/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "aoc2015/util" + "maps" + "regexp" + "slices" +) + +func calculateMaxHappiness(data map[string]map[string]int) int { + people := slices.Collect(maps.Keys(data)) + permutations := util.Permutations(people) + + happiness := util.ArrayMap(permutations, func(permutation []string) int { + total := 0 + + for index, person := range permutation { + indexLeft, indexRight := util.NeighborIndexes(index, len(permutation)) + neighborLeft := permutation[indexLeft] + neighborRight := permutation[indexRight] + leftHappiness := data[person][neighborLeft] + rightHappines := data[person][neighborRight] + + total += leftHappiness + rightHappines + } + + return total + }) + + return slices.Max(happiness) +} + +func part1(data map[string]map[string]int) int { + return calculateMaxHappiness(data) +} + +func part2(data map[string]map[string]int) int { + people := slices.Collect(maps.Keys(data)) + data["Me"] = map[string]int{} + + for _, person := range people { + data["Me"][person] = 0 + } + + return calculateMaxHappiness(data) +} + +func main() { + lineRegex := regexp.MustCompile(`^([a-zA-Z]+) [a-zA-Z ]+(gain|lose) (\d+) [a-z ]+(\w+).$`) + reader := func(name string) map[string]map[string]int { + lines := util.ReadLines(name) + mappings := map[string]map[string]int{} + + for _, line := range lines { + match := lineRegex.FindStringSubmatch(line) + + var value int + if match[2] == "gain" { + value = util.StringToInt(match[3]) + } else { + value = util.StringToInt(match[3]) * -1 + } + + person := match[1] + neighbor := match[4] + + if _, ok := mappings[person]; !ok { + mappings[person] = map[string]int{} + } + + mappings[person][neighbor] = value + } + + return mappings + } + + util.TestRuns("13", reader, part1, part2) + util.SolutionRuns("13", reader, part1, part2) +} diff --git a/d13/test-runs/0.txt b/d13/test-runs/0.txt new file mode 100644 index 0000000..82e9d8a --- /dev/null +++ b/d13/test-runs/0.txt @@ -0,0 +1,12 @@ +Alice would gain 54 happiness units by sitting next to Bob. +Alice would lose 79 happiness units by sitting next to Carol. +Alice would lose 2 happiness units by sitting next to David. +Bob would gain 83 happiness units by sitting next to Alice. +Bob would lose 7 happiness units by sitting next to Carol. +Bob would lose 63 happiness units by sitting next to David. +Carol would lose 62 happiness units by sitting next to Alice. +Carol would gain 60 happiness units by sitting next to Bob. +Carol would gain 55 happiness units by sitting next to David. +David would gain 46 happiness units by sitting next to Alice. +David would lose 7 happiness units by sitting next to Bob. +David would gain 41 happiness units by sitting next to Carol. \ No newline at end of file diff --git a/util/array.go b/util/array.go index ed54afa..fda2083 100644 --- a/util/array.go +++ b/util/array.go @@ -21,3 +21,21 @@ func ArrayFilter[T any](sequence []T, predicate func(T) bool) []T { return data } + +func NeighborIndexes(index int, sequenceLength int) (leftIndex int, rightIndex int) { + var indexLeft, indexRight int + + if index-1 < 0 { + indexLeft = sequenceLength - 1 + } else { + indexLeft = index - 1 + } + + if index+1 > sequenceLength-1 { + indexRight = 0 + } else { + indexRight = index + 1 + } + + return indexLeft, indexRight +} diff --git a/util/combinatorics.go b/util/combinatorics.go index 4788436..a554cb1 100644 --- a/util/combinatorics.go +++ b/util/combinatorics.go @@ -13,3 +13,35 @@ func Doubles[T any](set []T) (subsets [][]T) { return result } + +// Returns all permutations of a given array +func Permutations[T any](array []T) (permutations [][]T) { + var helper func([]T, int) + res := [][]T{} + + helper = func(arr []T, n int) { + if n == 1 { + tmp := make([]T, len(arr)) + copy(tmp, arr) + res = append(res, tmp) + } else { + for i := 0; i < n; i++ { + helper(arr, n-1) + + if n%2 == 1 { + tmp := arr[i] + arr[i] = arr[n-1] + arr[n-1] = tmp + } else { + tmp := arr[0] + arr[0] = arr[n-1] + arr[n-1] = tmp + } + } + } + } + + helper(array, len(array)) + + return res +}