SRMに参加しました


前々からやろうやろうと思っていたけれど引き延ばしていたことのひとつ、競技プログラミングにチャレンジしてみました。今回参加したのはSRM561、初のTopCoder参加です。
結果は惨澹たるものに。 参加した部屋の中で一人だけscoreがマイナスでした。
というか普通いくら初参加でも最終スコアがマイナス ってそうそういないんじゃないだろうか。

以下感想記。

SRMで検索して出たページの通りに参加登録をし、わくわくしながらカウントダウンを待つことしばし。
スタートの合図とともにまずやったことは問題をgoogle先生に投げることです。翻訳しないと問題文すら読めないというレベル。多分文章自体はそんなに難しい英語を使っていないんでしょうけれど、短時間であの分量を読むことは無理かと。英語嫌いだし。
念の為googleとYahoo!の両方に翻訳文を投げて、返ってきた滅茶苦茶な日本語を元に問題文にようやくとりかかる。
問題は250,500,1000の三種類。数字がそのまま解いた時の得点を表していて、当然得点が高ければ高いほど難しい。

まずは250から……ふーむ、これソートすればいいだけかな?
で、とりあえず手で選択ソートを書いてみる。
短時間かつそらで書けるか不安だったけどなんとかそれっぽいのになった。
まぁ最初だしそんなに凝ったもの考えなくていいよね、とアリーナのコンパイルボタンを押すとエラーが返ってきた。
手元のEmacsではエラーを全部潰したのにおかしいな? と思ったらどうも提出形式が決まっている様子。英語だからあんまよくわかんなかった。てっきり標準入力で入ってくる形式だけなんだと思ったらクラス名や関数名、引数のとる型まで指定されてる。
ん? クラス? そもそも僕普段クラスとか使ったことがないんですが……
仕方なくその場でクラスの書き方を検索する。すぐに見つかることは見つかったが、 慣れない。
慣れないことはやっぱりするべきじゃないもので、セミコロンのつけ忘れとか名前空間解決演算子(だっけ?) を忘れたりだとかくだらないミスをする。
標準入出力で全部済ませていたAOJとは随分勝手が違うなぁと少し面倒に感じた。

ようやく直し終わってコンパイル。よしよし、今度は通った。
そんなわけでテストをしてみる。でもテスト結果の読み方がわからない。
一番上にNOって出るのはこれは答えが間違ってるってことか? 首を傾げる。
correct return って書いてあるし多分正解かどうかを表しているんだろう。
というわけで再度ソースを読み直す。どうもループの末尾で一個余分にカウントしてたみたいだ。
とりあえずその場しのぎに答えとなる返り値から1引いてみる。
今度はテストしたらYESになった。これでいいのかな。
そしてそのままなんとなくでSUBMIT(提出)を押してしまった。
自分でも「こんなんで通るわけ無いよな」とか思ってはいたのだけど、出来上がって舞い上がってたかもしれない。反省しよう。

そのまま500の問題に挑戦。
コーディングに与えられた時間は75分?あるのだけどこの時点で半分は使い切っていた。
500の問題も翻訳にかける。文章が長い。しかも意味がわからない。
日本語でも英語でも変わらないであろうテストデータとその解答例を照らし合わせつつ問題を理解しようとする。読み終わって分かったことは「これは無理だ」ということ。今の僕には到底解けそうになかった。それも残り30分弱で? 無理無理。
仕方ないので提出の体裁だけ整えてみる。クラス作って関数と引数を条件通りに設定して……そういえばこれをこのまま出したらどうなるのだろう?
さっき提出したコードはロクにテストしてなかったのにスコアが入った(これが勘違い)
ということはこれも提出すればわずかなりとも加点されるのではないだろうか。
なにもしないよりマシだよな、ということで提出。テストするまでもなく落ちるのが分かっていたけれど提出点があると勘違いしていたのだから仕方がない。
実際にはすべてのテスト(他人からの攻撃:チャレンジ、開催側のテスト:システムテスト)をくぐり抜けなければ点にならないのだが。

そんなわけで最初のステップ、CODING PHASEで2問提出した。実質解いたのは1問だったが。
そうこうする内に制限時間が来て一旦 INTERMISSION 、5分間の休憩に。特にすることもない。
 休憩が終わると他人のコードのあら探し、CHALENGE PHASEが始まる。
だがそもそも他人のコードとか読めないし読めたところでどんなデータで攻撃できるのかさっぱり見当もつかない。とりあえずこういうのは端っこのデータや極端なデータが抜け落ちがちだと聞く。ろくすっぽ考えもせずにデータを打ち込んでみる(これが本日2つ目の間違い)
すると見事に自爆しマイナス点を食らってしまった。下手な攻撃はしないほうがいいですね。
そんな間抜けを晒している間に自分の解答はすべて撃沈されてしまった。
Challenge Succeeded というステータスが横に並んでいる。最終的に部屋の中でこのステータスが表示されたのは僕だけだった。他の人はほぼPassed System Test、つまり撃墜もされず正解した人々だった。
まぁ一問目なのだから彼らにとっては当然なのだろうけれども。

そんなわけで結果的に僕は一問も解けず、それどころか不用意な攻撃によってスコアがマイナスという最終結果を残してSRM初参加を終えた。

感想としてはTop Coderが広まることはまず無いな、という具合。
やらせたいことにたどり着くまでが難しい。軽くTop Coderで検索をかけてでてくる情報って、大概が登録方法に重点をおいてるものだった。中には丁寧にアリーナのスクリーンショットコンパイル、テスト、サブミットのボタンなんかを載せてるところもあったけど、提出形式に触れてるところはあんまりなかった。
実際にこんなコードを提出しました、っていうところでようやく「あ、標準入出力じゃないんだ」という具合。コンパイル結果出力やテスト結果の見方、テストデータの打ち込み方など説明しているものは見られない。さらっと「コンパイルをする、テストができる」とかそれくらいしか書いていない。
それくらい自分でなんとかしろ、とか手元の環境で十分クリアできる問題じゃないかという言い分もあるかもしれないが、これ全部「英語ができれば困らない」部分だと思う。
感想として述べた「広まらない」っていうのはつまり英語の壁が問題だというつもりで書いた。

あとよく競技プログラミングに関してはそんなに専門的な知識や経験はいらないと言われている。
* for文、if文、while文が分かる
* 配列が扱える
* 文字列が扱える
* 関数がどういうものか分かっている
* ライブラリがどういうものか分かっている
これで十分だと。だから初心者だって大歓迎なのさ、とも。
しかし正直それは詐欺広告に近いんじゃないかと思っている。
少なくともTopCoderに関してはこれでは無理だろう。
どうしてそう明確に言い切れるのかという理由は 「クラスがない」からなのだが……いや、僕のように書き方を検索すれば何とかなる程度なので、これはただの揚げ足です。
しかし、今回参加した問題はTopCoder側から引数にはint型のvectorを使うようにと指定があったし……と、これはC++を使わなければいいだけの話か。
うーむ、そう考えていけばこれで十分なのだろうか。
でもこの要件を満たす人間が全員SRMの問題を解けるというのは大いに疑問だ。
初っ端がこんな結果に終わってしまった人間のひがみなのかもしれないが、けどどうなんだろう。
一問も解けない問題に取り組んで楽しいのか?
解いたと思って意気揚々と提出したら即撃墜されて楽しいのか?
なんとか相手のミスをついたと思ったら失敗してマイナス つけられて楽しいのか?
正直今回僕は記念受験のようなつもりで参加していたから気にならなかったが、
これは楽しくないだろう。数学の問題集なんかと同じだ、正解できなければ面白くない。
とりあえず、競技プログラミング初心者をまずTopCoderに引きこむのだけは絶対にやめたほうがいいと思う。
最初はAOJくらいからがいいんじゃなかろうか。

僕はAOJからやり直すことにします。
当分TopCoderはやらない。
解けないから面白くない上に深夜開催で眠いわ明日に響くわ良いことがひとつもないと判明したからだ。



// TopCoder直後に書いたので滅茶苦茶な文章になってしまった。後日修正するかもしれない。// ともかく今はただ眠い。