「Advent of Code」に Kotlin で参加する
この記事は、Kotlin Advent Calendar 2022 の 3 日目の記事です。
概要
Advent of Code という「アドベントカレンダーのプログラミングの問題で解く版」のようなサービスがあります。
過去から JetBrains はスポンサーとして参画しており、今年(2022 年)も参画します。
Advent of Code は Kotlin の公式ドキュメントとして紹介されています。また、過去の年には数日分の Kotlin を用いた解答動画が YouTube チャンネル Kotlin by JetBrainsより公開されています。そのため、Kotlin の勉強教材として向いています。
本記事では、どのように 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 問目に挑戦できません。
JetBrains は、スポンサーとして参画しています。
また、JetBrains 社が用意してテンプレートリポジトリを利用して、リポジトリの Description などを記述することで、成績優秀者には賞品も送られるそうです。
公式(Kotlin by JetBrains)から解説動画も載せられているので、数日分には Kotlin による解答方法もみれます。
参加方法
下準備
Advent of Code 2021 の Day1 のコードで参加してみます。
まずは、Advent of Code にログインをしてください。GitHub アカウントなどの SNS アカウントからログイン可能です。
ソースコードは JetBrains から Kotlin 用の Advent of Code のテンプレートが用意されています。
これを利用して Advent of Code に取り組みます。
テンプレートから新しいリポジトリを作成したら、ローカルにクローンしてください。
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 の自動翻訳とソースコードがあるので、なんとなく意味がわかります。
解説によると、template にはUtils.kt
に標準入力が用意されていることがわかります。
さっそくUtils.kt
から修正しています。改行ごとに分割し String 型を Int 型に変換します。
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]]
といった次第です。
fun part1(input: List<Int>): Int {
return input.windowed(2).count { (a, b) -> a < b }
}
あとは、Day01 の問題用データをコピー&ペーストして、Day01.txt を置き換えて実行します。
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 から賞品をもらうための準備も公開されていたので、興味がある方は登録してみてください。
Discussion