🫖

「Advent of Code」に Kotlin で参加する

2022/12/02に公開

この記事は、Kotlin Advent Calendar 2022 の 3 日目の記事です。

https://qiita.com/advent-calendar/2022/kotlin

概要

Advent of Code という「アドベントカレンダーのプログラミングの問題で解く版」のようなサービスがあります。

https://adventofcode.com/

https://en.wikipedia.org/wiki/Advent_of_Code

過去から JetBrains はスポンサーとして参画しており、今年(2022 年)も参画します。

https://blog.jetbrains.com/kotlin/2022/11/advent-of-code-2022-in-kotlin/

Advent of Code は Kotlin の公式ドキュメントとして紹介されています。また、過去の年には数日分の Kotlin を用いた解答動画が YouTube チャンネル Kotlin by JetBrainsより公開されています。そのため、Kotlin の勉強教材として向いています。

https://kotlinlang.org/docs/advent-of-code.html

本記事では、どのように Kotlin で参加してKotlin by JetBrainsの動画を参考にして勉強できるのか紹介します。
なお、2022 年時点の内容となっていますので、時間経過とともに変更される可能性がることをご了承ください。

Advent of Code について

Advent of Code とは、2015 年から開始したサービスです。
アドベントカレンダーと似たように 12 月 1 日から 12 月 25 日まで毎日問題が 2 問ずつ出題されます。
1 問クリアするたびに、Advent of Code でメダルを取得できます。
そのため、25 日で 50 個のメダルを集めることが目標になります。
言語は限られておらず、問題のテストデータに対して解答を入力すれば完了です。日付ごとに 1 問目をクリアしなければ 2 問目に挑戦できません。

https://en.wikipedia.org/wiki/Advent_of_Code

JetBrains は、スポンサーとして参画しています。
また、JetBrains 社が用意してテンプレートリポジトリを利用して、リポジトリの Description などを記述することで、成績優秀者には賞品も送られるそうです。
公式(Kotlin by JetBrains)から解説動画も載せられているので、数日分には Kotlin による解答方法もみれます。

https://blog.jetbrains.com/kotlin/2022/11/advent-of-code-2022-in-kotlin/

参加方法

下準備

Advent of Code 2021Day1 のコードで参加してみます。
まずは、Advent of Code にログインをしてください。GitHub アカウントなどの SNS アカウントからログイン可能です。

ソースコードは JetBrains から Kotlin 用の Advent of Code のテンプレートが用意されています。
これを利用して Advent of Code に取り組みます。

https://github.com/kotlin-hands-on/advent-of-code-kotlin-template

テンプレートから新しいリポジトリを作成したら、ローカルにクローンしてください。

hands on advent of code

Intellij を開いて、インデックスの作成が終わったら準備完了です。

intellij

問題を解く & 解説をみる

Day 1の問題は「--- Day 1: Sonar Sweep ---」です。
問題内容をざっくりと言うと、「n 番目の数字が n-1 番目の数字よりも増加した(increase)回数を数えなさい」です。
標準入力に渡される値は以下のようになっています。

199
200
208
210
200
207
240
269
260
263

こういった問題は、最初はどうやって標準入力を渡すのかでつまずくと考えています。しかし、Kotlin by JetBrainsの解説動画があるので大丈夫です。さっそく見ていきましょう。

Day 1 の解説動画は以下です。解説は2:11ごろから始まります。
自分は英語が得意ではないですが、比較的ゆっくり解説してくれるのと、YouTube の自動翻訳とソースコードがあるので、なんとなく意味がわかります。

https://www.youtube.com/watch?v=76IzmtOyiHw

解説によると、template にはUtils.kt に標準入力が用意されていることがわかります。
さっそくUtils.ktから修正しています。改行ごとに分割し String 型を Int 型に変換します。

src/Utils.kt
fun readInputAsInts(name: String) = File("src", "$name.txt")
    .readLines().map { it.toInt() }

そして、Day01 のソースコードを以下のように修正しました。
List<int>型に対して windowed という拡張関数が存在することを知りました。windowed は List から引数(Int)の単位の List を前方から作成します。たとえば、[1, 2, 3, 4][[1, 2], [2, 3], [3, 4]]といった次第です。

src/Day01.kt
    fun part1(input: List<Int>): Int {
        return input.windowed(2).count { (a, b) -> a < b }
    }

あとは、Day01 の問題用データをコピー&ペーストして、Day01.txt を置き換えて実行します。

src/Day01.kt
fun main() {
    fun part1(input: List<Int>): Int {
        return input.windowed(2).count { (a, b) -> a < b }
    }

    fun part2(input: List<Int>): Int {
        return input.size
    }

    // test if implementation meets criteria from the description, like:
    // val testInput = readInputAsInts("Day01_test")
    // check(part1(testInput) == 1)

    val input = readInputAsInts("Day01")
    println(part1(input))
    println(part2(input))
}

part1 の出力結果が答えになります。
Day 1の入力フォームに入力しましょう。
正解だったとき金メダルをもらえるはずです。そして次の Day 1 の問題が公開されます。

まとめ

解説動画を参照にした解答方法は以上になります。
問題と解説は英語ですが、問題自体は比較的難易度がやさしく、参加の敷居が低いと考えています。
2022 年の Advent of Code に Kotlin で参加する方法も、2022 年バージョンで公開されています。JetBrains から賞品をもらうための準備も公開されていたので、興味がある方は登録してみてください。

https://www.youtube.com/watch?v=mWfYF7IW1u8

Discussion