Compare commits
2 Commits
0ad418ed1f
...
24a65d3752
| Author | SHA1 | Date | |
|---|---|---|---|
| 24a65d3752 | |||
| 0bd0ec5f1e |
114
internal/2015/DayThirteen/code.go
Normal file
114
internal/2015/DayThirteen/code.go
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package daythirteen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"advent-of-code/internal/registry"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var inputPattern = regexp.MustCompile(`(\w+) would (gain|lose) (\d+) happiness units by sitting next to (\w+)\.?`)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Register("2015D13", ParseInput, PartOne, PartTwo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildHappinessMap(data []string) map[string]map[string]int {
|
||||||
|
happinessMap := make(map[string]map[string]int)
|
||||||
|
|
||||||
|
for _, line := range data {
|
||||||
|
matches := inputPattern.FindStringSubmatch(line)
|
||||||
|
person := matches[1]
|
||||||
|
operation := matches[2]
|
||||||
|
value, _ := strconv.Atoi(matches[3])
|
||||||
|
neighbor := matches[4]
|
||||||
|
|
||||||
|
if happinessMap[person] == nil {
|
||||||
|
happinessMap[person] = make(map[string]int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if operation == "gain" {
|
||||||
|
happinessMap[person][neighbor] = value
|
||||||
|
} else {
|
||||||
|
happinessMap[person][neighbor] = -value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return happinessMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllPeople(happinessMap map[string]map[string]int) []string {
|
||||||
|
people := make([]string, 0, len(happinessMap))
|
||||||
|
for person := range happinessMap {
|
||||||
|
people = append(people, person)
|
||||||
|
}
|
||||||
|
return people
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePermutations(items []string) [][]string {
|
||||||
|
if len(items) == 0 {
|
||||||
|
return [][]string{{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result [][]string
|
||||||
|
for idx, item := range items {
|
||||||
|
remaining := make([]string, len(items)-1)
|
||||||
|
copy(remaining[:idx], items[:idx])
|
||||||
|
copy(remaining[idx:], items[idx+1:])
|
||||||
|
|
||||||
|
for _, permutation := range generatePermutations(remaining) {
|
||||||
|
result = append(result, append([]string{item}, permutation...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateTotalHappiness(arrangement []string, happinessMap map[string]map[string]int) int {
|
||||||
|
totalHappiness := 0
|
||||||
|
arrangementLength := len(arrangement)
|
||||||
|
|
||||||
|
for idx := range arrangementLength {
|
||||||
|
currentPerson := arrangement[idx]
|
||||||
|
leftNeighbor := arrangement[(idx-1+arrangementLength)%arrangementLength]
|
||||||
|
rightNeighbor := arrangement[(idx+1)%arrangementLength]
|
||||||
|
|
||||||
|
totalHappiness += happinessMap[currentPerson][leftNeighbor]
|
||||||
|
totalHappiness += happinessMap[currentPerson][rightNeighbor]
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalHappiness
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseInput(filepath string) []string {
|
||||||
|
content, _ := os.ReadFile(filepath)
|
||||||
|
return strings.Split(string(content), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func PartOne(data []string) int {
|
||||||
|
happinessMap := buildHappinessMap(data)
|
||||||
|
allPeople := getAllPeople(happinessMap)
|
||||||
|
|
||||||
|
fixedPerson := allPeople[0]
|
||||||
|
remainingPeople := allPeople[1:]
|
||||||
|
permutations := generatePermutations(remainingPeople)
|
||||||
|
|
||||||
|
maxHappiness := math.MinInt
|
||||||
|
arrangement := make([]string, len(allPeople))
|
||||||
|
arrangement[0] = fixedPerson
|
||||||
|
|
||||||
|
for _, perm := range permutations {
|
||||||
|
copy(arrangement[1:], perm)
|
||||||
|
totalHappiness := calculateTotalHappiness(arrangement, happinessMap)
|
||||||
|
if totalHappiness > maxHappiness {
|
||||||
|
maxHappiness = totalHappiness
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxHappiness
|
||||||
|
}
|
||||||
|
|
||||||
|
func PartTwo(data []string) int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
26
internal/2015/DayThirteen/code_test.go
Normal file
26
internal/2015/DayThirteen/code_test.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package daythirteen
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
var testInput = []string{
|
||||||
|
"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",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPartOne(t *testing.T) {
|
||||||
|
expected := 330
|
||||||
|
got := PartOne(testInput)
|
||||||
|
if got != expected {
|
||||||
|
t.Errorf("PartOne() = %d, want %d", got, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user