Skip to Content

Advent of Code 2022 - Day 25, in Kotlin - Full of Hot Air

Kotlin solutions to parts 1 and 2 of Advent of Code 2022, Day 25: 'Full of Hot Air'

Posted on

It’s Christmas morning, and that means one thing - the end of another year of Advent of Code puzzles! This closes out my eighth year participating and the sixth year of blogging about my solutions. While I enjoy Advent of Code very much, and look forward to it every year, I’m always a bit relieved and sad when it’s over. I hope you had a much fun solving these as I have. Some of the puzzles have been challenging, and not like the kind of code I usually write at work or for my own purposes. But that’s why we do this, to learn new things and hopefully have some fun. I want to thank you for reading my blog during Advent of Code 2022, and I hope you got something out of it.

If you’d rather just view code, the GitHub Repository is here .

Puzzle Input

We won’t do any parsing or manipulation of the input today, other than to declare it as a property on Day25 so we can refer to it later. We’ll take it in a List<String>.

class Day25(private val input: List<String>) {

}

⭐ Day 25, Part 1

The puzzle text can be found here.

While today’s puzzle only has one part, we will write two functions - one for converting SNAFU String inputs to Long numbers, and another for doing the reverse. Let’s start with String (a SNAFU) to Long, which we’ll implement as an extension function.

// In Day25

private fun String.fromSnafu(): Long =
    fold(0) { carry, char ->
        (carry * 5) + when(char) {
            '-' -> -1
            '=' -> -2
            else -> char.digitToInt()
        }
    }

We will fold over all of the characters in the String the fromSnafu function is called on. For each char, we figure out its decimal value using a when expression and add that to the carry multiplied by 5. Why 5? Imagine if we were doing this with base 10 and converting the string “23” to an integer one character at a time. First we’d handle 2, and then handle 3. But we have to multiply 2 by 10 to get 20 so 20+3 works out properly. The same applies in our case with base-5, even if two of the symbols represent negative numbers.

Next, we’ll reverse this with an extension function on Long. I had a bug here for a while, not realizing that I needed to use Long and not Int for all of this. D’oh! At any rate, we’ll set up a sequence starting with the number we’re called with, and continuously adding 2 and dividing by 5. We do this until we hit 0. For each successive value provided from the sequence generator, we take its value mod 5, and look up which character that maps to (0, 1, 2, =, or -). We join these characters into a String via joinToString taking care to specify that the separator we want is a blank string, and then reverse the results (because we are building the result String backwards).

// In Day25

private fun Long.toSnafu(): String =
    generateSequence(this) { (it + 2) / 5 }
        .takeWhile { it != 0L }
        .map { "012=-"[(it % 5).toInt()] }
        .joinToString("")
        .reversed()

By using these two functions to convert SNAFU to Long and back, we can solve today’s puzzle! We’ll use sumOf from the Kotlin Standard Library over the input after converting each line from a SNAFU number, and then convert the result back to a SNAFU number.

// In Day25

fun solvePart1(): String=
    input.sumOf { it.fromSnafu() }.toSnafu()

Star earned! Thanks for sticking with me for all these Advent of Code 2022 posts.

Further Reading

  1. Index of All Solutions - All posts and solutions for 2022, in Kotlin.
  2. My Github repo - Solutions and tests for each day.
  3. Solution - Full code for day 25
  4. Advent of Code - Come join in and do these challenges yourself!