77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
|
package day_01
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// task:https://adventofcode.com/2024/day/1
|
||
|
// short summary - we are offered two lists of location IDs,
|
||
|
// and we need to compare the smallest ID from one list with the
|
||
|
// smallest from the other one,
|
||
|
// and calculate the difference between them
|
||
|
|
||
|
func SolveBasic(input string) int {
|
||
|
firstIds, secondIds := loadSortedLocationIds(input)
|
||
|
|
||
|
diff := 0
|
||
|
for i := 0; i < len(firstIds); i++ {
|
||
|
diff += abs(firstIds[i] - secondIds[i])
|
||
|
}
|
||
|
return diff
|
||
|
}
|
||
|
|
||
|
// task:https://adventofcode.com/2024/day/1#part2
|
||
|
// short summary - the initial comparison wasn't that good,
|
||
|
// so instead we need to check how often values
|
||
|
// from the first list appear in the second one, multiply the value with the number
|
||
|
// of appearances and sum all of that up
|
||
|
func SolveComplex(input string) int {
|
||
|
firstIds, secondIds := loadSortedLocationIds(input)
|
||
|
|
||
|
// we could have avoided this and run a binary search and count for every number
|
||
|
// but this was simpler and perhaps even faster to run
|
||
|
idOccurrences := map[int]int{}
|
||
|
for _, locationId := range secondIds {
|
||
|
// this works for missing values as idOccurrences[location]
|
||
|
// will return 0 if no value is present for numbers
|
||
|
idOccurrences[locationId] = idOccurrences[locationId] + 1
|
||
|
}
|
||
|
|
||
|
sum := 0
|
||
|
for _, locationId := range firstIds {
|
||
|
// this works for the same reason as above
|
||
|
sum += idOccurrences[locationId] * locationId
|
||
|
}
|
||
|
return sum
|
||
|
}
|
||
|
|
||
|
// helper methods
|
||
|
|
||
|
func loadSortedLocationIds(input string) ([]int, []int) {
|
||
|
lines := strings.Split(input, "\n")
|
||
|
// we create slices of the required size at start
|
||
|
firstIds := make([]int, len(lines))
|
||
|
secondIds := make([]int, len(lines))
|
||
|
|
||
|
for i, line := range lines {
|
||
|
if _, err := fmt.Sscan(line, &firstIds[i], &secondIds[i]); err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sort.Ints(firstIds)
|
||
|
sort.Ints(secondIds)
|
||
|
|
||
|
return firstIds, secondIds
|
||
|
}
|
||
|
|
||
|
// go doesn't have an Abs(int) int func so we write our own
|
||
|
func abs(value int) int {
|
||
|
if value < 0 {
|
||
|
return -value
|
||
|
}
|
||
|
return value
|
||
|
}
|