Advent of Code 2019 が楽しかったので布教したい

今年のゴールデンウィークは暇だなぁと思いながらネットを巡回していた時、ふと見つけた Advent of Code 2019 が思いのほか面白く、2日間ほどかけて一気に解いてしまいました。

終わったあとふと TwitterGoogle で検索をかけてみたところ、日本語圏では言及がほとんどなかったので、この面白さをもっとたくさんの人々に共有したいと思い記事を書きました。

Advent of Code とは

まずは簡単に形式的な説明を。

Advent of CodeEric Wastl 氏が2015年から毎年12月に開催している、プログラミングコンテストアドベントカレンダーを融合したようなイベントです。

開催期間中の12月1日から25日にかけて、プログラミングで解く問題が1日あたり2問ずつ、合計50問投稿されます。

リアルタイムで参加する場合は、解く速さに応じてポイントが割り振られ、ランキングがつけられるようです。しかしウェブサイトは常時動いているので、イベント後もいつでも問題を解くことが出来ます。

問題には入力データファイルが添付されており、参加者は自分で書いた解答プログラムをそのデータファイルに対してローカル環境で走らせます。出力をウェブサイトのフォームから送信し、一致していれば問題クリアです。サーバ上でプログラムを評価する形式ではないので、好きなプログラミング言語やライブラリを使うことが出来ますし、デバッグも比較的容易です。

何が面白いのか

私が Advent of Code をやってみて面白いと感じたのは、大きく分けて次の3点です。

  1. 作り込まれたゲーム性
  2. 1日2問ずつ出題される問題
  3. バラエティに富んだ問題セット

作り込まれたゲーム性

f:id:nya3jp:20200506131133p:plain
2019年のカレンダー(初期状態)

前述の通り、Advent of Code はプログラミングコンテストであると同時にアドベントカレンダーです。

アドベントカレンダー (Advent calendar) は、クリスマスまでの期間に日数を数えるために使用されるカレンダーである。待降節の期間(イエス・キリストの降誕を待ち望む期間)に窓を毎日ひとつずつ開けていくカレンダーである。すべての窓を開け終わるとクリスマスを迎えたことになる。

アドベントカレンダー - Wikipedia

ウェブサイトの問題一覧 は ASCII アートで書かれたアドベントカレンダーになっています。最初は地味ですが、問題を1問解くごとに星⭐が1個カレンダーに追加され、デザインも少しずつカラフルに変化していきます。最終的にすべての問題(50問)を解いてクリアするとカレンダーが完成するというわけです。この少しずつ出来上がっていくカレンダーを眺めるのが一つの楽しみになっています。

また、すべての問題がクリスマスにちなんだ一貫したストーリーに沿っており、問題文自体が楽しい読み物になっています。Advent of Code 2019 第1問 は次のように始まります。

他の惑星にプレゼントを届ける途中、太陽系の辺境でサンタが遭難してしまった! ワープ装置を使って地球に戻るためには、50個の星を観測して現在位置を正しく計算しなければならない。クリスマスを無事に迎えるために、50個の星のデータを集めてサンタに届けてほしい。

Santa has become stranded at the edge of the Solar System while delivering presents to other planets! To accurately calculate his position in space, safely align his warp drive, and return to Earth in time to save Christmas, he needs you to bring him measurements from fifty stars.

このあと主人公は地球をロケットで飛び立ち、太陽系の様々な星に立ち寄りながらサンタを救出しに行くこととなります。果たしてサンタの宇宙船で何があったのか? それは全ての問題を解くと明らかになります。

1日2問ずつ出題される問題

前述した通り、問題は1日あたり2問ずつ出題されます。

最初は各日あたり1問目のみ見ることが出来るようになっています。1問目を正解することで初めて2問目が見られるようになります。

2問は密接に繋がっており、入力データはまったく同じものを使います。実際、ほとんどの場合、1問目の解答プログラムの大部分を2問目の解答プログラムに再利用することができます。

2問の関係は様々です。1問目では入力データを正しく解釈できていることを確認するのみで、2問目で本来のタスクを解く、ということもあります。問題の仕様は同じだが入力データを10,000倍に膨らませて解けと言われることもあります。時には入力の一部を書き換える指示が出て、問題の性質が大きく変わってしまうこともあります。

1問目の解答プログラムを書いている間は2問目の問題が分からないので、2問目では問題がどのように変わるだろう、と考えながら解答プログラムを設計するのも楽しみの一つです。

バラエティに富んだ問題セット

問題のジャンルの広さも大きな魅力です。特に2019年の問題セットは特徴的になっています。

2019年の問題セットの半分ほどはクラシックなアルゴリズム問題からなっています。シミュレーション・グラフ・計算幾何・数論などからの出題があります。一般的なプログラミングコンテストに比べると難易度は高くないように感じますが、前述した2問制により面白さが増しています。

残りの半分は Intcode という独自に定義されたプログラムを使った問題です。問題セットの序盤で数問に渡って Intcode の仕様が与えられ、処理系を実装させられます。その後の問題では入力データファイルとして Intcode のプログラムが与えられ、それを自分で実装した処理系で実行してタスクをこなすこととなります。

たとえば 13日目の問題 Care Package ではブロック崩しのプログラムが Intcode で与えられます。このプログラムを実行しているところを動画にしてツイートしてくださった方がいました。

このゲーム、人力でプレイすることも出来るのですが、すべてのブロックを消してクリアするにはとても長い時間がかかります。ゲームプレイを自動化するプログラムを書く必要があるというわけです。

まとめ

というわけで、Advent of Code の魅力を紹介しました。

プログラミングの問題を楽しく解けるようにとても上手くデザインされたイベントだと思いますので、時間のあるときに是非トライしてみてください。

私もまだ 2019 年の問題セットしかやっていないので、過去の問題セットもやってみようと思います。

参考