Advent of Code 2022 - Day 2, in Kotlin - Rock Paper Scissors

Kotlin solutions to parts 1 and 2 of Advent of Code 2022, Day 2: 'Rock Paper Scissors'

Posted on

Today’s solution might not be the most technically challenging solution I’ve ever written for an Advent of Code puzzle, but I’m happy with it. I think this puzzle, more than most of the others, illustrates that sometimes writing down the answer and looking it up when asked is not a bad solution. In the puzzle today there are really only nine combinations of input so we have a good opportunity to pre-calculate our answers for both parts. Sure, there are a lot of fun ways we could have solved the puzzle today, but I like the simplicity of this solution.

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

Puzzle Input

Today we don’t need to manipulate the input at all. To get the input file into our solution class, we’ll load the input as a `List<String>`, each element representing a row as it exists in the input. We define our `input` as a `private val` in the constructor of the `Day02` class, as we’ll use it later on.

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

}
``````

⭐ Day 2, Part 1

The puzzle text can be found here.

When I first saw this puzzle, I thought “OK, we’ll go through the input, do a bunch of math, and sum the answers”. Then I took a closer look and realized that the math wasn’t that complicated (to me) and there were only nine outcomes. So why not take an opportunity to simplify things? Instead of doing math as we look at the input line by line, why not calculate all the answers up front?

To do this, we’ll set up a `Map<String, Int>` to store our answers for part one. The `String` key represents the file input as-is (originally, I had removed the space, but why bother? It’s easier to read this way I think), and the `Int` value represents the score the key combination creates. I left the math in mostly so I could debug as I went, but I think keeping it in add clarity and doesn’t cause any real overhead. For example, when we see `A Y` we know that our opponent as picked Rock and we have picked Paper. For this combination we get 2 points for picking Paper and 6 points because Rock beats Paper . We repeat this process for all nine combinations.

``````// In Day02

private val part1Scores: Map<String, Int> =
mapOf(
"A X" to 1 + 3,
"A Y" to 2 + 6,
"A Z" to 3 + 0,
"B X" to 1 + 0,
"B Y" to 2 + 3,
"B Z" to 3 + 6,
"C X" to 1 + 6,
"C Y" to 2 + 0,
"C Z" to 3 + 3,
)
``````

Once we know the value of each of the nine combinations, we can run through the `input` as-is and sum the corresponding values from the map to get our answer. Thanks to `sumOf`, we can sum and map in one step.

``````// In Day02

fun solvePart1(): Int =
input.sumOf { part1Scores[it] ?: 0 }
``````

Star earned! Onward!

⭐ Day 2, Part 2

The puzzle text can be found here.

Part two uses the same method as part one, but we calculate the answer set with different rules. In this case, “A Y” is worth 4 total points - 1 point for picking Rock (because we’re asked to draw) and 3 points for the draw. I’ll admit having the math stare me in the face here helped with some debugging.

``````// In Day02

private val part2Scores: Map<String, Int> =
mapOf(
"A X" to 3 + 0,
"A Y" to 1 + 3,
"A Z" to 2 + 6,
"B X" to 1 + 0,
"B Y" to 2 + 3,
"B Z" to 3 + 6,
"C X" to 2 + 0,
"C Y" to 3 + 3,
"C Z" to 1 + 6,
)
``````

And just like in part one, we sum the values for each input returned by the answer map for our solution:

``````// In Day02

fun solvePart2(): Int =
input.sumOf { part2Scores[it] ?: 0 }
``````

Star earned! See you tomorrow.