Week 50
- Reading
- Digital Minimalism - Cal Newport
- The Witcher The Last Wish - Andrzej Sapkowski
- Flow: The Psychology of Optimal Experience - Mihaly Csikszentmihalyi
- Grieving a death in the family
- Being extremely reflective on life I want to live
- Catching up Car maintenace
- Replaced aging tires
- change oil
- wash, claybar, and wax
- check timing belt
- Finishing putting Christmas up
- Updated homelab Truenas to support tailscale and nfs file mounts
- promptly spent the next 6 hours looking through family photos
A little late to the party but starting on the advent of code for the year.
Day 1 - Problem
compare 2 lists of numbers.
- Order the both lists of numbers smallest to largest
- find the difference between each item in both ordered lists
- Sum this the total of the absolute value from the above step
- Find the frequency at which each item in left list occurs in the right list
- mulitply frequency by the numeric value of the list item
- sum the total
Approach
Load data input memory, and creat 2 sorted lists
- copied provided file into txt file
- Read raw text input
- parse the input input to slices of ints
- reorder the lists each time a new value is added to it
1 file, err := os.ReadFile("./input.txt")
2 if err != nil {
3 log.Fatal(err)
4 }
5 inputTxt := fmt.Sprintf("%s", file)
6 lists := strings.Split(inputTxt, "\n")
7 var listA, listB []int
8 for _, v := range lists {
9 output := strings.Split(v, " ")
10 if len(v) > 0 {
11 outputA, _ := strconv.Atoi(output[0])
12 outputB, _ := strconv.Atoi(output[1])
13 listA = appendToOrdered(listA, outputA)
14 listB = appendToOrdered(listB, outputB)
15 }
16 }
17 return listA, listB
The ordering of the list took me way to long to implement, and in the end, my solution was more or less brute force
- range through the slice, comparing the to be inseted int to each element within the slice
- after finding the first occurence of a value greater or equal to the new element, Add the new element at the current indexed position
- create a slice of slice of all the remaining elements within the slice, after the entry point
- append the slice of slice
The way go handles slice length and capacity was a sticking point for me here. Mulitple times I got tripped up working a a slice that didn't have enough capacity, or would have erronous length added, leading to 0 values incorrectly added to the list.
Learned that
append()
willnot increase a slice cap unless it is required for the new elements.
1func appendToOrdered(list []int, number int) []int {
2 var newList = make([]int, len(list), cap(list)+1)
3 if len(list) < 1 {
4 return append(list, number)
5 }
6 for i, v := range list {
7 if v >= number {
8 newList[i] = number
9 newList = newList[:i+1]
10 count := 1
11 for _, v2 := range list[i:] {
12 if i+count+1 >= len(newList) {
13 newList = append(newList, v2)
14 } else {
15 newList[i+count] = v2
16 }
17 count++
18 }
19 return newList
20 } else {
21 newList[i] = v
22 }
23 }
24 return append(list, number)
25}
Summing the total and toatlFrequency was straight forward enough since I was already iterating through the slices.
1 left, right := getInput()
2 total, similarity := 0, 0
3 for i, v := range left {
4 distance := right[i] - v
5 d := math.Abs(float64(distance))
6 total += int(d)
7 similarity += findSimilarity(v, right)
8
9 }
10 fmt.Printf("total: %v\n", total)
11 fmt.Printf("Similarity: %v\n", similarity)
Learnings
- poked around the os package in the stdlib for reading files on the filesystem
- Go HAS A SORT PACKAGE
- of course it does.
alt approach without custom sorting algorithm
1file, err := os.ReadFile("./input.txt")
2 if err != nil {
3 log.Fatal(err)
4 }
5 inputTxt := fmt.Sprintf("%s", file)
6 lists := strings.Split(inputTxt, "\n")
7 var listA, listB []int
8 for _, v := range lists {
9 output := strings.Split(v, " ")
10 if len(v) > 0 {
11 outputA, _ := strconv.Atoi(output[0])
12 outputB, _ := strconv.Atoi(output[1])
13 listA = append(listA, outputA)
14 listB = append(listB, outputB)
15 }
16 }
17 slices.Sort(listA)
18 slices.Sort(listB)
19 return listA, listB
20}