撤退戦から始める競技プログラミング~背水の陣と優雅なる撤退戦
この記事はCompetitive Programming Advent Calendar 2017の11日目の記事である。
アドベントカレンダーといえば、該当日の0時には公開されているものであるが、私が住んでいる国が日本であるという保証はないし、文化や宗教上の都合で太陽太陰暦を採用しているかもしれないし、そもそも同じ世界線にいるかも怪しいので、一概に遅刻しているということはできないのである。
とはいえ、この日本のこの世界線の一般的住人から見ると遅刻しているように見えることは事実であるので、本当に申し訳ないと思っている。以後気を付けますのでご勘弁ください。
撤退戦から始める競技プログラミング
この文章は主には競技プログラミング始めようと思っているけど、なかなか手を出せないとか、継続が困難とかいう人たちに向けて書かれているのである。そのため技術的ノウハウみたいなものは一切身につかないため、そういうのを求めている人は人はざっと目を通して、いいねボタンを押すか、目を通さないでいいねボタンを押すかすればいいと思うのだ。まあ、対象者にとっても役に立たない可能性は大いにあるのだが。
どちらかといえば、マラソン系コンテスト向けに書かれています。
1.継続するために何から始めるか
「競技プログラミングは地頭ゲーム!頭が3つあるキングギドラとか半裸でダイナミックプログラミン!できる人のみ参加が許されるのだ!」
というようなことを言う人がいます。大体私とかだと思います。
でも大丈夫。地頭がなくて知識がなくても、参加はできるし、大抵の場合、点数も1点くらいは取れます。競プロ怖くない。
「地頭ないのに参加しちゃってこいつ粋がってやがるとか思われないかな?」
そんなあなたも大丈夫。地頭勢は我ら凡庸地底人を歯牙にもかけていないので、そんなことを思われることはありません。競プロ怖くない。
継続すれば強くなるということは基本的によっぽどのことがない限り当たり前であるが、分かっていても継続できない。その理由は大体以下の3つくらいであると思う。
1、点が取れず、負けばかりで楽しくない
2、目指すところが高すぎて走り始める前に倒れてしまう
3、楽しいとかとは別の目的(就活とか)でやってる
1、点が取れず、負けばかりで楽しくない
人間には自尊心というものがあり、負けというものは認めたくないものである。そんなときにはまず、開始前からの撤退戦から戦いを始める。
HHMMの問題確認した。面白そうではあるが、かなり難しくもある。とりあえずひとまず問題だけ記憶しておく。今週末は用事があるし、ひょっとすると来週末も怪しいので、なんかここのとこタイミング悪い。ちょうど暇なときにはマラソン行われない感がわりといつもある。
— P沼的 (@PnumaSON) 2017年11月29日
まずは忙しくて参加ができないから、私の点数がクソだったとしても私がクソなんじゃなくて時間がないんだなあという免罪符を設置する。これによって、たとえ精神と時の部屋を利用して時間を錬金しているとしても、他者から見た目は忙しくて参加する時間の少ない人である。いくら点が低くても時間のない人であるから仕方がないのである。
そもそも最初から高い順位を取るなんて地頭勢じゃないと無理なので、今の点からこつこつ上げていけばいいのであって、気にするところではないのである。なにかしらノウハウや実装法が得られれば勝ちなのである。
万年煮え切らない順位マンの異名を確固たるものとしていくこの姿勢を何とか脱却したいマン。まあ、今回は俺の中では即物的なものではなく、チャレンジングな内容だったので糧にはなったが、51位か。明日まではネガティブモードになるな。
— P沼的 (@PnumaSON) 2016年10月3日
ぎりぎり賞品を逃してやや心に来ていても糧になったのでいいのである。
2、目指すところが高すぎて走り始める前に倒れてしまう
「いずれは競プロでブイブイ言わせてコンテスト上位をかっさらい続けて億万長者になっちゃるぜ」
その心意気やよし。だが今じゃない。
競プロに限ったことではないが、遠すぎる目標、高すぎる到達点は危険である。大目標として掲げるのはよいが、小さな目標もたて、それを達成することでモチベーションを維持することは大切である。
とりあえずルールだけ読んでおけば、俺は最強なわけだから、仕事中になんかいい案思いつくだろ。思いついたら、それぶん投げて、改良は相当いい案思いついた時だけにして、CodinGameやるか。つーかTopCoderのページなにがなにやら無茶苦茶見づらい。
— P沼的 (@PnumaSON) 2017年4月13日
やる気があんまりなくてもまずルールだけでも読む。一歩一歩が大切である。
これに①で紹介した技を組み合わせる。すなわち、
今日を含めた三連休にどうにもできない用事があって愛知に戻らねばならないことがわかっていたので、CodeinGameに手を出していなかったのだけど、(ほかにも体調とかの問題もあったが)100万円は大きいのでほしい。とりあえず、ルールくらいは見ようかな。
— P沼的 (@PnumaSON) 2016年10月10日
エクセレント!完璧な布陣である。
コンテストの中にはゴールド、シルバー、ブロンズといった順位による区切りを設けているコンテストがある。そういったコンテストの場合、「まずブロンズ突破を目標」とかそういった目標が立てれるので活用すべし。ほかには同じくらいの能力を持った競プロ勢を勝手にライバル認識して、「とりあえずあの人に勝つ」みたいなのも有効である。
3、楽しいとかとは別の目的(就活とか)でやってる
これ、いいと思います。私の初めての競プロとの出会いは完全な偶然で、就活とかとは全く関係なかったのであるが、その次の動機はこれでした。ただ、これは始めた時期によってはできるだけ効率よく即物的にいい順位を取らなければいけない。そのため難易度が高いし、モチベーションも微妙になることが多い。おススメはあまり誰にも知られていないような競プロの世界大会に参加すること。就活には世界何位って言えるし、人数が少ないと結構勝てるので趣味勢にとっても楽しくていいかもしれない。
2.いつ撤退するのか
私の場合、いつでも撤退しようと思ったときに撤退するのである。
十中八九時間計測関数がまともに動いていなさそうというのが原因なんだけど。まあ、うまくいっていたとしても、30位目指せるスコアではないので、今回は撤退が妥当。試行回数で殴れるかと思ったけど、結構殴れないことが分かったので、次回はしっかり組むかな。
— P沼的 (@PnumaSON) 2017年4月22日
もちろん時間をかければかけるほどノウハウは貯まる。楽しければいくらでもやってもいいと思う。しかし嫌だなと思えば仕事でやってるわけではなく、趣味でやっているのだから、いつでも撤退できる。精神を削るほどじゃない。
競技プログラマなのにACMでないの?とか聞くなよ。俺は本気で趣味でやってんだ。面白い思えば出るし、そうじゃなきゃ出ない。手軽なら出るし、面倒なら出ない。誰かがコーチ見つけてきて相乗りでかつ、実力を求められてないなら出るかもしれんが、そういう流れはなかった。
— P沼的 (@PnumaSON) 2015年6月26日
撤退戦で大事なところは撤退した後である。何位で撤退したかなんて特に意味はない。撤退後に実装のどういう部分に問題があったか、ほかの人はどういう風に実装したかちゃんと終わった後に確認をするのである。自分ではかなり時間をかけて実装した点と同じ点を自分の10分の1くらいの時間で実装してしまう人たちがいる。どういうのがスマートな実装であるか終了後に見て学ぶことで、より素早く楽していい点が取れるようになるのである。
楽していい点を取るために効率よく学ぶには、
1、ちゃんと読んでルールを熟知している
2、ちょっと作ってみて、つまずきポイントが分かっている
3、ほかの人の解法、考え方、ソースコードを読む
である。
最後に
別に解けなくても死ぬわけじゃないし、順位悪かったって知ったこっちゃないのだ。これも競プロに限ったことではないが、ポジティブさはいろいろなことをこなしていく際に大事である。
まあ、なんだ。それでも俺は最強なので、土曜の朝とか、日曜の夜とかでなんとかなるまいかとは思っているよ。今日はどうかって?疲れたからコードは書かないよ。設計はより詳細に脳内に作成されてきたので、そこそこはパワー出るんじゃないかな。
— P沼的 (@PnumaSON) 2017年5月19日
ただし、趣味であるから大丈夫であるが、仕事上での根拠のないポジティブさは危険であるので、節度を保ったポジティブさをお勧めするのである。
ここまで読んでいただき、何も得るものがなくイライラした方は適度なストレスにより脳が活性化されたことを喜べばいいし、得るものがあった人は良かったと思います。
背水の陣について書こうと思ったが、大変長くなったし、この件はまた今度ということにする。