Skip to content
Threadsnappers

Day 1 - Calorie Counting 🍗

In this post I’ll be walking you through my day 1 Advent of Code 2022 solution. The first step in every solution is to of course read the input. Here the test input is stored in a text file with the name Day01.txt. For this I used the default readInput() function provided in the AoC 2022 official repo template which returns a List<String>.


Analyzing the input

The input consists of numbers which represents the calorie count of the meals taken by the Elves. The inventory of one Elf is separated from the next by newlines. Let’s take a look at the sample input to make it clear.

1000    # first elf
2000
3000

4000    # second elf

5000    # third and so on
6000

7000
8000
9000

10000

This contains the inventory data of five elves. The sum of the numbers gives the total calories in the snacks carried by each elf. Part 1 involves finding the number of calories being carried by the elf with the most calories.


Part 1

Grouping the food of each Elf

The input for the first two elves initially looks like this ["1000", "2000", "3000", "", "4000"]. Notice the blank string after 3000? That marks the separator between two adjacent elves. The joinToString() function joins every element in the list to a String with each element separated by the separator which in this case is a space.

readInput("Day01").joinToString(separator = " ", transform = { it })

The result is a String which looks like

1000 2000 3000  4000

The blank string after 3000 now has double space in the string. To group the calories of each Elf, the string is split at every double space.

.split("  ") // Double space

The input has now been reduced to ["1000 2000 3000", "4000"].

Computing calory count of Elves

Next step is to once again split the string in each element and sum it up. The map() function applies an operation to every element in a collection. Every element has to be processed like so:

  1. Split around every space.
"1000 2000 3000"" -> ["1000", "2000", "3000"]
  1. Convert every element in the list to Ints so that they can be added.
["1000", "2000", "3000"] -> [1000, 2000, 3000]
  1. And finally, add them up to get a single value.
[1000, 2000, 3000] -> 6000

Using map, the above three steps can be done together.

.map { it.split(" ").sumOf { n -> n.toInt() } }
val calories = readInput("Day01")
    .joinToString (separator = " ", transform = { it })
    .split("  ")
    .map { it.split(" ").sumOf { n -> n.toInt() } }

The result is a List of Int with total calorie count carried by each Elf. Let’s assign this to a variable calories so that it can be used again for part 2.

Once the calorie count of all the elves has been computed, there’s only one thing left to do - print the highest calory count. For this we can use the max() function.

val part1 = calories.max()

Solution

val calories = readInput("Day01")
    .joinToString (separator = " ", transform = { it })
    .split("  ")
    .map { it.split(" ").sumOf { n -> n.toInt() } }
val part1 = calories.max()

Part 2

Part 2 is pretty much the same as part 1 except that here you need to find the top three elves with most number of calorie count in their inventory and sum it up. For this I sorted the calories list and then summed up the last three elements.

Solution

val part2 = calories.sorted()
    .takeLast(3)
    .sum()

takeLast(n) returns the last n elements in the list and sum() adds it up. There you have it, we’re one day clear of the 25 day advent! 🎉

Full Solution

fun main() {
    val input = readInput("Day01")
    val calories = input.joinToString (separator = " ", transform = { it })
        .split("  ")
        .map { it.split(" ").sumOf { n -> n.toInt() } }
    val part1 = calories.max()
    val part2 = calories.sorted()
        .takeLast(3)
        .sum()
    part1.println()
    part2.println()
}

Open in Playground GitHub