Advent of Code 2021 in Kotlin
Advent of Code is the advent calendar for programmers. A puzzle is posted every day which you can solve with the programming language of your choice. It started in 2015 and I have already seen it for years. However, I have been reluctant to join because I feel I don’t have enough time. I finally decided to try it this year to practice and learn more Kotlin.
I worked on the puzzles at the same day (in my local timezone). Some of the code are not efficient (!!, nested loops, brute force, et al.) as I am hoping to finish them quickly. I’ve been making them as clean and readable as possible, so I can understand it when I look back to it in the future. I post the solutions to https://github.com/jomartigcal/advent-of-code and research how I can improve my code or change the approach to the solution.
I was only able to solve the puzzles for the first 15 days as I have less spare time and need to focus on some other projects. It was still a great experience and I plan to try the other puzzles when I have more time in future.
Using Kotlin to solve the daily puzzles is great. There are standard functions I can take advantage of to solve puzzles in just a few lines of code. There are still so many that I have yet to discover. Here’s what I learned while doing the Advent of Code 2021:
.groupingBy { it }.eachCount()
To count the number of times an item appears in an array or list, you can use groupingBy { it }.eachCount()
binary.toInt(2)
An easy way to convert a binary string to decimal is by using toInt(2).
concatToString()
A character array can be converted to a string using concatToString()
replaceAll
You can change the elements of a list with the replaceAll passing in the function to apply to each element. For example, to change the contents of a list of numbers to the square of each number, you can use replaceAll { it * it}
single()
If a list contains only one element, you can use .single() to get the only item from the list. It will throw an exception if the list is empty or has more than 1 elements. You can use singleOrNull() so it will return a null instead.
mapKeys and mapValues
You can quickly modify a map’s keys or values with mapKeys or mapValues. For example, to change the keys to uppercase you can use mapKeys { it.keys.uppercase(Locale.getDefault()) }. If you want to replace the values with each one’s length, you can use mapValues { it.value.length }
minOf and maxOf
The minOf and maxOf functions return the smallest and largest value based on the function applied to each element. For example, if you have a list of the first 8 Greek alphabet letters, you can use minOf { it.length} and maxOf { it.length } to get the smallest (3 for eta) and largest (7 for epsilon) length of the letters.
digitToInt()
To convert a number in a character type to an integer (e.g. ‘1’ to 1), you should not use toInt(). It will return the ASCII conversion of the character (e.g. for ‘1’ that is 49). The function you should use is digitToInt().
associate
You can quickly convert a list to a map using the .associate function and passing in both the key and the value for each item.