ICFP2011

20 Jun

Twitterで分けて書くとちょっと見づらい長さを書きたい時にどこに書いたものかと考えて、日記の存在を思い出しました。

今回は数年ぶりの参加で、@riesz先生と一緒にMox Camlというチーム名で出ました。@riesz先生による記述はこちら

前日の夜遅くにPNGを解析して”Lambda The Gathering”であることを知るも、”Lambda”よりも”The Gathering”に引っ張られてギャザリングのルールを教えてもらったりしていました。カードを何枚手元に置けるとか。。。ここで”Lambda”の方を学んでおけばもうちょっとマシな結果だったかもしれないです。

当日朝起きて、問題を読みながら移動。合流して問題の内容を確認。ギャザリングについて調べつつチーム名を決めました。(Mox RubyとかMox Pearlとかいう強いカードがあるらしいです)

シミュレータはどうみても関数型言語で書くべきだろうということで、OCamlで書くことにしました。OCamlは私が全然書けないという問題はありましたが、昔exampleプログラムとかは書いたことあるはずなので採用。シミュレータに全ステートを出力させて、C++のルーチンで手を考えるという可能性も検討しましたが、自由度が下がりそうなので避けました。

夕方ころ、match構文や再起の使い方を学んでいる時点で、@riesz先生がシミュレータを完成させました。このシミュレータの完成度は高く、後に2箇所小さな修正が入るものの、他は完全に動作していました。初日の夕方にこのレベルのものがあったのは大きなアドバンテージだったと思います。

その後どういう抽象度で思考ルーチンを書くかという議論をしました。各ステートに置いて、複数の取り得る手から最善の手を取るという観点から、後に評価関数を作れるような仕組みにすることや、ある程度大きなまとまり(attack(i, j))のブロックでプログラムを構成し、一度決めた動作は必ず実行するという仕組みにすることなどを検討しました。議論の末、相手の攻撃などで状態が常に変わり続けることを考え、ステートレスに毎回状況を判断して最善のことをするという構成にしました。

Exampleをきちんと見ていなかったため、attackやhelpなどの使い方が分からず、いろいろいじってみたりGoogle先生をフル活用したりして、なんとか使い方を「発見」していました。それをステートレスを前提としたコードにある程度見やすく書く方法を模索したりして、この日は終了。

2日目は「いろいろな機能を追加する日」であると信じて始まり、必要に応じてHelpを実行したりする機能の追加などをしていました。Invalidでの負けが多かったので、HelpやAttackの構築途中や発行時点で引数の値を確認する仕組みを作ったりなど。この時点ではまだ繰り返しが実現することを知らず、「くり返しとかはできないようにルールを作ってあるんじゃないかな」とか今考えればとんでもないことを言っていました。ルールを読み直していた@riesz先生がApplication Limitについて書かれていることを発見し、もしかしてループが可能なのではないかという説が再び浮上し、SKIをひたすら捏ねくり回した末に(まだ親切なExampleの存在を知らず)ループが構成可能なことを発見して驚いていました。

2日目未明〜3日目は、@riesz先生はループによるHelp爆弾を作り、その後も新たな兵器の開発に注力していました。その間にぼくは新たに得られた「殺されて爆弾を埋め込まれたらおしまい」という知見を元に「殺されない」ようにする努力をしていました。敵が構成中のAttackを読みだしてスロットが死ぬ危険があれば早急にHelpの用意をはじめるといった仕組みや、ステートレスの利点を生かしてHelpやAttackの対象を柔軟に変更しつつも、行動の変化によって構築途中の式が無駄になりにくい仕組みを作っていました。

最終的に出来上がったものは、8割方勝つくらいのものでした。調子がよければExcellentですが、そうでなければ普通に戦って勝ちます。負ける時も、Excellentで負けたり、戦って競り負けたり。

もうちょっと早い段階からSKIで何が出来るのか真剣に考えていれば、もうちょっといい結果が出せたかもしれないです。問題文は隅々までよく読みましょうということですね。あとは、2人チームというのは中途半端だったかもしれないです。2人しかいなくてもコード共有や他人のコードを理解する作業などの手間はかかるので。プログラムが小さいうちは「パッチができあがった頃にはプログラムの構造が変わっていて全部書き直し」みたいなことが結構ありました。普通ならシミュレータ係とAI係みたいに分けるところが、@riesz先生が一瞬でシミュレータを作ってしまった一方ぼくはOCamlの文法を調べていために分担などなくなったというのも原因だと思いますが。

学んだこと:
・問題文はよく読みましょう。
・モジュール分けとか、コードの管理をどうするかとか大切。
・学校の授業はちゃんと聞いておきましょう。SKIコンビネータとか聞いたことはあったのに。
・関数型言語1つくらいちゃんと使えるようにしておいても悪くない。

とても教育的な問題でした(少なくともぼくにとっては)。計算理論についてもですし、関数型プログラミング言語についても勉強になりました。何日も1つの事に集中する経験ができて、久しぶりに関数の世界に触れられて、楽しかったです。すばらしい問題を作っていただいた運営者様と、足手まとい感満載のぼくに付き合ってくれた@riesz先生に感謝感謝です。

では、おやすみなさい。

Leave a Reply

Your email address will not be published.