Kotlin logo

Kotlin

A concise multiplatform language developed by JetBrains

News

Advent of Code 2021 in Kotlin, Day 1

In this post, I’m going to walk you through my solution to the Advent of Code 2021 Day 1 task. Of course, I used Kotlin to solve it! 

The input for the task is a text file, where each line is a number that represents a measurement of the depth of the seafloor. The task is to count the number of measurements where the depth increases. For example:

199 (N/A - no previous measurement)
200 (increased)
208 (increased)
210 (increased)
200 (decreased)
207 (increased)
240 (increased)
269 (increased)
260 (decreased)
263 (increased)

In the sample input above, there are 10 measurements. The depth of the seafloor increases 7 times, and that would be the correct answer for the task.

To read the file, I used the following line of code:

File("input.txt").readLines()

The result was a list of strings, but I actually needed a list of integers. Hence, I came up with the following helper function to read the input file and transform it into a list of integers:

fun readInputAsInts(name: String) = File("src", "$name.txt").readLines().map { it.toInt() }

Since the task is to compare each number to the previous one, I needed to read the numbers in pairs: the first and the second, then the second and the third, and so on. The Kotlin standard library provides a very useful function for this situation: windowed().

val input = readInputAsInts("Day01")
val list: List<List<Int>> = input.windowed(2)

The result was a list where each element was a pair of integers that I needed to compare and see whether the second integer was greater.

The count function with a predicate as a parameter is perfect for this situation. I was able to implement the whole solution as follows:

val input = readInputAsInts("Day01")
input.windowed(2).count { (a, b) -> a < b }

As is usually the case in Advent of Code puzzles, the requirement changes in the second part. I now needed to work with a three-measurement sliding window.  For the sample input above, this meant that I needed to read three numbers (199, 200, 208), then read another triple (200, 208, 210), calculate the total for both triples, and compare them. Then I would count the number of cases where the second total was greater than the first. In this example 199+200+208 < 200+208+210, meaning this case counts.

The solution that was appealing to me was to optimize the condition for this task a bit. I needed to compare the totals of the triples as follows: 199+200+208 <=> 200+208+210. I saw the same two numbers on both sides of the equation, which meant I could just eliminate these figures, leaving me with 199 < 210. 

Each pair of triplets contained a total of only four numbers, so I was able to group the input by four elements and compare the first number to the last:

input.windowed(4).count { it[0] < it[3] }

The solution to the second part of the challenge turned out to be rather simple! 
I have published the code for my solution to the Advent of Code GitHub repository if you’d like to compare it to yours. Have fun with Advent of Code this year!

image description