ICFP Programming Contest 2012 (後編)

というわけで,今回の戦いの様子を時間軸にそって記録しておく.時刻はかなり適当である.

07/13

  • [21:00]数分遅れで問題が公表される.
  • [21:30]落石の条件がややこしかったので,紙の上に図を描いて問題の内容を整理する.
  • [21:30]探索が基本になるだろう,ということで速度を稼ごうと思って C++ でコードを書くことに決める.シミュレーターぐらいは Ruby あたりで書くことも考えたが,後にソルバーから再利用することを見越してすべて C++ で通すことを決める.
  • [01:00]googletest とか boost とかと戯れているうちにこの日が終わる.

07/14

  • [11:30]起きる.おもむろに MBA を開いて,シミュレーターを書き始める.
  • [16:00]ユニットテストは最小限にする,と心に決めたはずなのに,ロボットの移動判定やら岩の落ちる部分やらをテストしようとしてはまり出す.
  • [16:30]この日はじめての食事をとるため外出する.
  • [17:30]帰宅したらとなりの保育園で夏祭りが始まっていた.19 時頃までかわさき音頭やらアンパンマン音頭やらポケモン音頭やらが太鼓の音とともに鳴り響く.
  • [17:30]シミュレーターをまたも一から書き直し始める.とはいえ書き直したコードはもとのコードと大差はなく,要するにおおよその設計は前のコードの時点ですでにできていた.ユニットテストの呪縛からはやっと解放される.
  • [22:00]ようやくシミュレーター(+検証器)の最初の版を書き終える.すでに lightning division は終わっている.
  • [22:30]手でいくつかの問題を解き始める.この時点でようやくこの問題が難しいことに気づく.戦意を喪失してほかのことを始める.
  • [01:30]うだうだしているうちにこの日が終わる.

07/15

  • [11:30]またもこの時間に起きる.ひとりなので早起きするモチベーションが湧かない.
  • [14:00]朝起きてから state.cc を読んだら「わかりにくい」と感じたのでおもむろに書き直す.
  • [15:00]検証器の表示にエスケープシーケンスで色をつけて見やすくする.
  • [15:00]「トランポリン」「ひげとひげそり」という新仕様が追加されていたことにようやく気づく.
  • [16:00]ひげとひげそりの実装を終える.コードをそれなりにきちんと書いていたことが役に立った(?).
  • [18:00]トランポリンの実装も終える.こちらはデータ構造をどうするかで結構悩んだのでそれなりに時間をとられた.
  • [18:30]夕食をとるため外出する.今度は近所の公園で盆踊り大会が開催されていた.我々だって祭り(それも世界規模の祭り)に参加しているわけだが,盆踊りのほうは体によさそうなのに対して,こちらの祭りはいかにも体に悪そうである.
  • [18:30]店で料理を待っている間は頭がふらふらしていた.食事をとるうちに少しずつ解消される.
  • [19:00]ようやくソルバーの開発を始める.もうすでにコンテストの 3 分の 2 近くが終わっている.
  • [21:30]「Higher-Order Rock」という謎仕様が追加されていた.もういいよ,とはじめは無視を決め込もうと思ったが,しぶしぶ実装を始める.
  • [22:00]奇跡的にわずか 30 分で実装が終わる.
  • [22:30]ついにプログラムだけでλが取れるようになる.とはいっても,まだ 1 個がとれるかとれないか,というレベルである.
  • [02:00]コードを整理するために,ソルバー(のできあがった部分)を再実装する.基本的な部品はできたものの,まだ一本につながっていない.就寝.

07/16

  • [10:30]起きる.9 時頃には起きようと思っていたが,結局この時間まで起き上がれなかった.
  • [12:15]ついに contest1.map がプログラムだけで解けるようになる.ママン,僕はやっとスタート地点に辿り着いたよ.
  • [13:30]デバッグ用のコードが効かないようにしたり,提出用の tarball を作るためのスクリプトを書いたりして,最初の版を提出する.ついに 0 点ではない点数が事実上確定する.
  • [15:00]今の今までコンパイラに最適化オプションを渡していなかったことに気づく.
  • [15:30]一度脱出に成功しても,ほかのルートがないかを探し続けるようにコードを改める.「すぐにあきらめない」ことから脳内でマツオカメソッドと勝手に命名される.
  • [16:00]気分転換を兼ねてペットボトルを買いに出たら,家のすぐ近くで蜂(アシナガバチ?)が受粉している光景を目にする.蜂に刺されたらそこでジ・エンドだなんて考えてもいなかったよ.
  • [17:00]ひげを何とかしようとコードを書いてみるも思ったように動かない.仕方がないので代わりに自分のひげを剃る.
  • [17:30]先のコードが動かないのは単にだめだめなバグがあったからにすぎなかった.それなりに動くようになったのでソルバーの一部として採用する.
  • [17:30]コンテストも終わりに近づいて打てる手が限られてきたため,焦りが先行して集中力が切れてくる.
  • [19:00]ひげのロジックを少し調整したり,ぽつぽつと湧いてくる segfault などのバグをつぶしたり,パラメーターをひとつ調整したり.そういえば SuperCon ではコンテストの終盤にパラメーターを調整するのが定番だった.しかし,僕のプログラムには調整できるパラメーターがひとつしかなかった.
  • [19:15]いよいよ本当に集中力が切れてしまったため,ラムダの代わりにハートフレーマーを集め始める.ちなみにプレイしていたのは PROC という裏面である.
  • [19:30]それすらも疲れたので PC の前に戻る.そのときに「何もできないときに限って岩の近くに移動する」というせこいハックを思いつく.
  • [20:00]そのハックを実装する.ほかのマップには影響がないままふたつのマップが新たに解けるようになる.
  • [20:15]もういいや,ということで最終版を提出して夕食を食べに出かける.

成果物

コードはこちら.github.com/yuizumi/icfpc-2012

ちなみに,サンプルに対する得点率(自分の点数/最高点数)は,マップごとに得点率をとって平均をとったものが 75.1%,合計点ベースだと 74.0% であった.ちなみに beard5.map ではなぜかλをひとつもとれないので,これを除いて計算するとそれぞれ 78.1% と 75.8% になった.