# Advent of Code 2018 - Day 1, in Kotlin

Kotlin solutions to parts 1 and 2 of Advent of Code 2018, Day 1: 'Chronal Calibration'

Posted on

It’s December 1st, and you know what that means - Advent of Code is back! I look forward to this every year, because I have so much fun with it. Like last year, I’m going to try and solve each puzzle on the day they are released, and write a blog post about it. This December is a busy month for me, so we’ll see how long I can keep that up!

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

Problem Input

Our input file has one integer (positive or negative) per row. I’m going to reuse my function from last year to load the file into a `List<String>` and pass that to the class that implements our solution. Because they are `Ints`, I may as well parse them while I’m at it…

``````class Day01(rawInput: List<String>) {

private val input: List<Int> = rawInput.map { it.toInt() }

}``````

#### Day 1, Part 1

The puzzle text can be found here.

Part 1 looks pretty simple, thanks to the `.sum()` extension already provided by Kotlin.

``````fun solvePart1(): Int =
input.sum()``````

That earns us our first star! Onward!

#### Day 1, Part 2

The puzzle text can be found here.

By reading carefully we know that we may have to loop through our list of inputs multiple times. This sounds like we could use an infinite sequence here. Thankfully, creating these in Kotlin 1.3 is pretty simple, so I’ll write an extension function that we can use in later problems if we need to.

``````fun <T> List<T>.toInfiniteSequence(): Sequence<T> = sequence {
if (this@toInfiniteSequence.isEmpty()) {
return@sequence
}
while (true) {
yieldAll(this@toInfiniteSequence)
}
}``````

All this does is check that our list isn’t empty (in this case it’s not, but I wanted to be thorough), and if not, just keep yielding the entire list. Kotlin will turn this into a sequence for us. Easy, right? The only weird part is having to label `this`. That’s because we’re in a coroutine scope here and we have multiple concepts of `this` going on at once, so we have to be explicit.

Since the sequence does most of the work for us, we can move directly to our solution:

``````fun solvePart2(): Int {
val frequencies = mutableSetOf(0)
var sum = 0
return input.toInfiniteSequence()
.map {
sum += it
sum
}
.first { !frequencies.add(it) }
}``````

In this case, we have two side effects: maintenance of the set of `frequencies` we’ve already seen, and the latest `sum`. Normally, I try to avoid code like this but the alternatives (one with `fold` and one recursive solution) were either too complicated or too slow (or both). In this solution, we use our infinite sequence to provide values that we map to the existing sum. This turns our sequence of inputs into a sequence of sums. Then we just stop the first time we’ve seen the sum before, by testing against our `frequencies` set.

This earns us our second star of the day!