Day 01. solutions
This commit is contained in:
parent
a9253ccb1b
commit
eff1d70d1c
|
@ -0,0 +1,8 @@
|
|||
package main
|
||||
|
||||
import _ "embed"
|
||||
|
||||
// File embedding all data required in final solutions
|
||||
|
||||
//go:embed day_01/data.txt
|
||||
var Day01Data string
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
|||
3 4
|
||||
4 3
|
||||
2 5
|
||||
1 3
|
||||
3 9
|
||||
3 3
|
|
@ -0,0 +1,76 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package day_01_test
|
||||
|
||||
import (
|
||||
"advent_of_code_2024/day_01"
|
||||
_ "embed"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//go:embed example_data.txt
|
||||
var BasicExampleData string
|
||||
|
||||
func TestBasicSolutionExample(t *testing.T) {
|
||||
result := day_01.SolveBasic(BasicExampleData)
|
||||
if result != 11 {
|
||||
t.Fatalf("Expected 11 received %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComplexSolutionExample(t *testing.T) {
|
||||
result := day_01.SolveComplex(BasicExampleData)
|
||||
if result != 31 {
|
||||
t.Fatalf("Expected 31 received %d", result)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"advent_of_code_2024/day_01"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
selectedDay := selectSolutionRun()
|
||||
|
||||
switch selectedDay {
|
||||
case "01-basic":
|
||||
fmt.Printf("Day 01. Basic: %d\n", day_01.SolveBasic(Day01Data)) // 2113135
|
||||
case "01-complex":
|
||||
fmt.Printf("Day 01. Complex: %d\n", day_01.SolveComplex(Day01Data)) // 19097157
|
||||
}
|
||||
}
|
||||
|
||||
func selectSolutionRun() string {
|
||||
selectedDay := ""
|
||||
if len(os.Args) == 2 {
|
||||
// if command line arg passed use that
|
||||
selectedDay = os.Args[1]
|
||||
} else if len(os.Args) == 1 {
|
||||
// otherwise ask user for the solution
|
||||
fmt.Printf("Enter the solution to be run: e.g. 01-basic,21-complex...\n")
|
||||
if _, err := fmt.Scan(&selectedDay); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// if too many arguments are passed return error message
|
||||
fmt.Printf("Invalid number of arguments\nUsage: %s day-basic|day-complex\n e.g. %s 01-basic", os.Args[0], os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
return selectedDay
|
||||
}
|
Loading…
Reference in New Issue