# Advent of Code 2019 - Day 1, in Kotlin

Kotlin solutions to parts 1 and 2 of Advent of Code 2019, Day 1: 'The Tyranny of the Rocket Equation'

Posted on

It’s December 1st and that means another round of Advent of Code has started! Like the last two years , I’m going to be solving each of the problems in Kotlin and blogging about them. While some people try to solve the problems as quickly as possible after they are posted, or solve them in the most efficient way, I try to solve them with a clear solution. Sometimes, those three approaches all align, but in most cases they do not. So sometimes you might see a solution that is a bit more inefficient in order to be more clear. I’m fine with that. For problems like this (generally things I wouldn’t roll into production), I’m fine with that. Code should be written for people, not machines.

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

Problem Input

We are given a file with a module weight on each row. Since our solutions are run from a unit test, we’ll load our sample input file in the test and pass it to our solution class as a `List<String>`. From there, we’ll parse those into a `List<Int>`, which we can refer to for our solutions.

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

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

}
``````

#### ⭐ Day 1, Part 1

The puzzle text can be found here.

As we can see, there’s a module weight calculation that will be executed a few times. In order to make our code a bit cleaner looking, we’ll define a `fuel` extension function on `Int`. We’re fortunate that Kotlin will do exactly what we need (rounding down) when doing the division here.

``````private fun Int.fuel(): Int = (this / 3) - 2
``````

Somebody might correctly point out that we don’t need the parenthesis there. However, I always put them in whenever I do any kind of arithmetic in code. This makes it more clear (to me), and I don’t want to assume that people who will read my code have memorized the operator precedence order.

This is a convenience for people only, the code that the computer runs will be the same either way.

If we look at the problem, we’re told to take each module, calculate the fuel it needs, and sum them together. We could do this with a `map` and a `sum`:

``````// We could try this...

fun solvePart1(): Int =
modules.map { it.fuel() }.sum()
``````

However, Kotlin’s standard library has a function that will let us do this a bit cleaner - `sumBy` . The `sumBy` function allows us to move the code we would have written in a `map` call to the `sum` function.

``````// Actually, let's make that simpler...

fun solvePart1(): Int =
modules.sumBy { it.fuel() }
``````

Running this will give us the correct answer to part 1 and our first star of 2019!

#### ⭐ Day 1, Part 2

The puzzle text can be found here.

There’s always a twist to these Advent of Code problems in Part 2. In this case, we can keep our `Int.fuel()` calculation, because it still holds. What we need now is a way to keep calculating fuel costs until the number is low enough to stop. As usual, there are a few different approaches we could take. We could do this with a `while` loop, or a `for` loop I suppose but when I see problems described like this I think recursion.

A recursive function is a function that calls itself. It breaks down work into smaller and smaller versions of itself until it reaches a stop condition.

So let’s write a recursive function called `fuelWithFuel` that performs our fuel cost calculation recursively:

``````private fun Int.fuelWithFuel(): Int =
if(this < 9)  {
0
} else {
val fuel = this.fuel()
fuel + fuel.fuelWithFuel()
}
``````
Update: Thanks to Karel Peeters in the #advent-of-code room in the Kotlin Slack for pointing out an optimization I missed in my haste! And thanks to Alexander Görtz for pointing out that we can avoid calculating fuel in more cases than I had realized (7 vs. 9 as a lower bound)!

Let’s go over that. First, we have our stop condition - return the 0 if we’re asked to calculate the fuel required for a value under 9. Why 9? Because anything less will yield a negative or zero fuel value.

Next, we get to the meat of our recursive function - breaking down the calculation into a smaller version of itself. In this case, we’re calculating the fuel cost given the weight (`this`), and add it to a recursive call to the cost for that fuel. As we recurse (calling `fuelWithFuel` from within `fuelWithFuel`), we will be dealing with smaller and smaller numbers until we hit the stop condition. At that point we’ll have our answer!

If we visualize this addition, it looks like the example in the problem description:

1969 is 654 + 216 + 70 + 21 + 5 = 966

Our solution to Part 2 ends up looking a lot like Part 1. The only difference is we’ll be calling our `fuelWithFuel` function:

``````fun solvePart2(): Int =
modules.sumBy { it.fuelWithFuel() }
``````

Running that earns us a star and closes out Day 1 of 2019!