AtCoderで青色になったので今までを振り返る

この記事には自分語りが多分に含まれます。苦手な方は十分にご注意ください。

この記事について

  2020 年 1 月 19 日の AtCoder Beginner Contest 152 で青色になることができました。初参加の 2018 年 10 月 27 日から 15 ヶ月ほどが経ち、丁度いい機会でもあるので、変色記事として自分と AtCoder を始めとする競技プログラミングコンテンツの関わりについて書き留めておこうと思います。変色する機会でもなければ書かないと思いますし、次の(上方への)変色機会が果たして来るのかどうかは怪しいので。
  内容は雑多に自身の背景や精進方法等を時系列順に記していくつもりですが、ほぼ自分語り主体の散文です。よほどの物好きでない限り、この記事は退屈に感じるでしょう。AtCoder の練習方針やその成果を中心とした内容は「緑色になるまで」から始まりますので必要であればそこからお読みください。

f:id:ose20:20200120032254p:plain

大学入学まで

  高校までは地元の家から近い学校に通っていて、特筆することもない学生生活を送っていました。ただ公立高校にしては珍しくカリキュラムが特殊で、数3の授業も受けられる文系のような課程を選択できたので、私はそれを選びました。今思い返せば、競プロの問題にも極限や期待値を考えるような問題があるので、当時の自分の選択にはいくらか救われている部分があると思います。
  パソコンはほとんど触ったことがありませんでした。情報の授業の時間に自分の何十倍ものスピードでタイピングをする新聞部員を見てかっこいいなと思った記憶があります。
  あと、これは私が競プロにハマったこととは多分無関係なのですが、自宅浪人という引き篭り生活をする某年間に家族以外との会話をほとんどしなかったので、大学に入ってから人との会話で言葉に詰まったりして大変でした。今はいくらか改善したと思います。

学部2年夏まで

  競プロが出てこないので飛ばします。しかしこの間にそこそこ真面目に単位を回収したことで、結果的にその後の競プロ精進の時間が確保できたように思います。専攻している学問分野を好きになれたことも私にとっては大事な財産です。あとレポートが書けなくて困ったのでタッチタイピングの練習をしました。

競技プログラミングに出逢うまで

  夏頃に、なんの前触れもなく気が触れてプログラミングに興味を持つようになりました。しかし計算機科学なんていう格調高い学問領域は疎か、パソコンにすら普段あまり触れない状態では何をしてよいのか皆目検討がつきません。Twitter で適当に情報を探しながら、progate をやってみたり、Udemy を見ながら簡単なアプリを作ってみたりしました、作ってみたりしたのですが、コンピュータやその他の情報技術について何にも知らない状態だからか、自分が理解できていないコードを書いてアプリが動いているのを見てもあまり感動しませんでした。ただ、その時見ていた Udemy の動画の講師の方が Project Euler を紹介していて、こちらはものすごく面白く感じました。他にも似たようなサイトがないか探してしていたところで偶然見つけたのが AtCoder でした。(大変お待たせしました。ここからは競プロの話になります。)

緑色になるまで

AtCoder に辿り着いたのは僥倖でしたが、まだ私には使える言語がありません。そこで友人に尋ねてみると、Python をお勧めしてくれました。入門者用の本も、もう自分には必要ないからと譲ってくれました。これで準備は整ったので、基本的な文法や入出力の仕方を調べながら、積極的にコンテストへ参加していきました。当時の ABC はまだ 4 問で、個人の感触としては、アルゴリズムやデータ構造のちょっとした知識がないと難しい問題が C で出ると 2 問しか解けないけど、D に難しい問題が置かれたときに C までの速解きに成功すると一気に伸びるというようなものだったと思います。この時期はひたすら ABC の AB 時々 C を埋めていました。

f:id:ose20:20200120045555p:plain
Python を使って緑まで

水色になるまで

  大学が春休みに入ったこともあり、アルゴリズムやデータ構造についてもう少し体系立った学習がしたいという思いから、『プログラミングコンテスト攻略のためのアルゴリズムとデータ構造』(通称:螺旋本)に手を出しました。また、この本のソースコードが C や C++ で書かれていたことや、参考にしようとした他の方のコードが C++ で書かれていることもあって、C++ をしようということになり、その前段階として結城浩先生の『C言語プログラミングレッスン』も一緒に読み進めていきました。
  この螺旋本には好きなところが 2 つあって、1 つはコンテストでは直接出題はされないけれど、アルゴリズムを理解する上で基本で大切な題材を取り扱っていることです。初等的整列の章では普段自分が何気なくしているトランプや UNO の手札の整列がアルゴリズムとして与えられたことに感動しましたし、木の章では探索順序について理解を深めることで、多くの問題について解答を容易にしてくれたように思います。もう 1 つはコンテストで直接役立つ典型アルゴリズムを幅広く学べることです。グラフ上の様々な最短距離問題や動的計画法の理解についての取っ掛かりを得たのは有意義だったと感じています。
  もう 1 つしていた練習として、~ ABC125 の水 Difficulty くらいまでの問題を周回するというものがありました。特に点数がついていないABC041 から前のセットは典型問題が多く、dp、尺取り法、いもす法、二分探索、累積和、木上の探索などの今でも即戦力で役に立つ武器があまり捻りのない形で置いてあるので、これらの問題を定期的に解き直して他の場面でも応用できるように練習しました。
  そんな練習が功を奏したのかどうかは定かではありませんが、平成最後の ABC で水色になることができました。

f:id:ose20:20200120050733p:plain
丁度 C++ に乗り換えた時期でもある

青色になるまで

 やったことは水色になるまでと基本的には変わらないんですけど、EDPC などの有志コンや Codeforces や AOJ にも少しずつ手を広げていきました。それに伴って、復習する問題を一元化して管理するためにスプレッドシートを使うようになりました。自分が挑戦した問題のうち、学びの大きかった問題をここに投入し、毎日ここから数問とり出して解き直し、問題の整理や定式化、正解となる方針を選択する理由などを話したり書いたり等の表現をすることが日課になりました(ちょうど別のある人にとっての Streak 繋ぎのように、私のやる気を維持する習慣のようになっています)
  あとは月並みではありますが、日々のコンテストでフィードバックを得ながら自分の弱点を探していき、それに対する対処(新しいアルゴリズムを覚える、特定分野の問題を多く解く、趣向の違うコンテストに出る、日々の練習で考察に使う時間を伸ばす・縮める、等)をして、またコンテストに出て...という繰り返しをしながら、精進もアドホックにしてきたように思います。今回青を達成できたコンテストも、少し前にたまたま LCA と包除原理の勉強をしていたのが幸いし、運よく時間内に解くことができました。

f:id:ose20:20200120061604p:plain
復習リスト 日に日に溜まって既に 300 問ほどあります

これから

AtCoder を始めるときに目標としていた色を達成できたので、とりあえずここで一区切りかなと思います。競プロを始めたことによっていくらか視界も広がりました。今はプログラミング言語について漠然とした興味があり、型理論やラムダ計算などの分野を勉強してみたいです。
  他には、まだ知らなかったり、ちゃんと理解していないデータ構造やアルゴリズムと仲良くなって、コンテストでうまく使えるようになりたいと思います。ここから 1 色上はまだまだ遠いですが、これからも練習を積んでできることを増やしていきたいです。
  最後になりましたが、同レート帯で競い合ったり、いろいろと御教授くださったり、様々な形で私と関わってくださった皆さん、いつもありがとうございます。私もコミュニティに恩返しができるように努めていきたいです。