DEV Community

Cover image for AoC Day 1 - Calorie Counting
Gal Elmalah
Gal Elmalah

Posted on • Updated on • Originally published at galelmalah.com

AoC Day 1 - Calorie Counting

The moment we have all been waiting for, December first. The end of the year is upon us and so those Advent of Code!

To those of you who don't know, AoC is a yearly programming competition where we try to help Santa do some funky sh**.
The competition itself is speed and time based, you can read more about it here.

Calorie Counting

Question

Part 1

We are given a list of numbers where each consecutive block of numbers represents the calories an elf is carrying with him.
For example

1000 - \
2000 -   -> an elf carrying 6000 calories 
3000 - /

4000

5000
6000

7000 - \
8000 -   ->  an elf carrying 24000 calories - the Maximum in our list
9000 - /

10000
Enter fullscreen mode Exit fullscreen mode

This problem seems simple enough, we need to split the string on empty lines then take each chunk and sum the numbers in it.
Once we obtained the various chunks (elf calories) we can search for the maximum value and we have our answer.

Parsing

Reading our input from a file named "input.txt"

func parse() []string {
    data, _ := os.ReadFile("./input.txt")
    chunks := strings.Split(string(data), "\n\n")
    return chunks
}

 // example output
// ["1000\n2000\n3000", "4000", "5000\n6000", ....]
Enter fullscreen mode Exit fullscreen mode

Why are we splitting the string on "\n\n"? The only char in an empty line is "\n", combining this with the line before we get "\n\n"

Summing the Chunks

Adding a new function that gets a string representing a chunk e.g 1000\n2000\n3000 and returns the sum of those numbers

func sumChunk(chunk string) int {
    sum := 0
    for _, num := range strings.Split(chunk, "\n") {
        v, _ := strconv.Atoi(num)
        sum += v
    }
    return sum
}
 // example output
// [6000, 4000, 11000, ....]

Enter fullscreen mode Exit fullscreen mode

to convert a string to an int we need to import the strconv package and use the atoi function (ascii to int).
Now its probably a good point to mention that in Go you deal with errors by returning them, in the function above the _ returned from atoi represent a possible error that we should deal with but since AoC is all about speed we can just tell the compiler to ignore it by naming it _.

Putting it All Together

package main

import (
    "fmt"
    "os"
    "sort"
    "strconv"
    "strings"
)

func main() {
    chunks := parse()
    //
    result := []int{}
    for _, chunk := range chunks {
        result = append(result, sumChunk(chunk))
    }

    sort.Ints(result)

    fmt.Println("Part 1")
    fmt.Println(result[len(result)-1])


}
Enter fullscreen mode Exit fullscreen mode

Again for the sake of speed we will just store all the results, sort them in ascending order, using Go sort package and use the last position as our answer.

I know, I know I could have found the max entry by comparing them inside the for loop but you'll see it will be worth it in part 2.

Part 2

In part 2 we are asked to return the sum of the 3 elves carrying the most calories i.e take our sorted array and sum the last 3 elements
We can easily tweak our answer to accommodate these new requirements by adding this line

    fmt.Println("Part 2")
    fmt.Println(result[len(result)-1] + result[len(result)-2] + result[len(result)-3])
Enter fullscreen mode Exit fullscreen mode

Alternatives?

I used sorting to get the biggest N elements in the array but there are other more performant approaches here like using a max-heap data structure BUT AoC is about keeping it simple and getting a valid answer ASAP so unless you know you'll have a performance problem it's better to go with the simpler and more naive solution most often.

You can find the complete code here
Thanks for reading!

Top comments (0)