競技プログラミングの経験がすごく役に立っている話
本日レバテック LAB で『「競プロは役立たない」論争はなぜ起こり、今も繰り返すのか?』というテーマの下記リンクの記事が公開された。
記事にもある通り『月刊・競技プログラミングは役立たない』と揶揄されるほど、競技プログラミング(以下競プロ)がいかに役に立たないかというブログや記事がちょくちょく投稿される。
AtCoder は素晴らしい事業をしていると心から思っているし、競プロが普及していることはとてもいいことだと思っている。
僕自身競プロは大好きなので(最近全然参戦できていないけど…)、「競プロやっても役に立たない」「競プロやってるやつはダメ」という言及を見ると、すごく微妙な心境になる。
僕が競プロを知ってやり始めたのは社会人になってからだ。
そのため、やり込むほどの時間は持てなかったが、のめり込んでいた時期もあり、それなりの時間をかけた趣味ではある。まだ TopCoder が主流の頃で、AtCoder がいまみたいに普及する以前の頃の話だ。なお、TopCoder の開催時間は夜中の 2 時とかだったりで、その時間まで起きてコンテストに出たりしたのは懐かしい思い出だ。
ちなみに実力的にはそんなに強い方ではないが、そこそこはできる方だと思う(TopCoder では最高で黄色、AtCoder では最高で青)。
競プロはすべてのエンジニアにとって役に立つものではないかもしれない。
しかし、少なくとも僕個人としては、競プロの経験が間違いなくソフトウェアエンジニアとしてとても役に立っている。
実際、ぼくが個人開発した賃貸検索サービスは、競プロでつちかわれた知識と技術が土台になっていると自信をもって言える。
ではどういった点がぼくには役に立ったのか。大きく分けて 3 つある。
アルゴリズムとデータ構造の知識とその応用力
競プロでは、アルゴリズムとデータ構造の幅広い知識とその応用力が必要となる。
様々な探索のアルゴリズムや木構造のアルゴリズム、動的計画法や文字列処理など、基本的なアルゴリズムやデータ構造を腹落ちして理解し、さらにそれらを使いこなす技術力が求められる。
これは裏を返せば、開発の現場でなにか問題に直面した時に、こういったデータ構造とあのアルゴリズムで効率的に解決できるということを考え出せる下地になる。
また、「並列処理や分散処理を用いない限りこれ以上の高速化はかなり厳しい」という限界も、それなりに自信を持って判断できるようになる。
常に計算量を意識する習慣
競プロでは「実装しているコードがどれくらいの計算量か」を常に意識する必要がある。
ここでいう計算量は、時間計算量と空間計算量の両方であり、すなわち「その実装がどれくらいの処理時間がかかり、どれくらいのメモリを使うのか」ということを意味する。
いままで様々なエンジニアと一緒に働いてきたが、競プロやコーディング面接対策をちゃんとしたことのない人で、これらの意識を正しく持っている人はわりかし少ない。
明らかに全探索でまったく問題ないような場合に、ムダに計算量を削ろうとしてあえて複雑な実装をしていたりというケースは何度か見てきた。
最近もなにかの記事で、高々 9000 のデータに対して毎秒の処理をする際に、あえて O(N) の実装を避け、複雑なアルゴリズムを実装しているのを見かけた。ぼくだったら自信をもって O(N) の全探索のシンプルな実装を選ぶと思う。だって高々 9000 のオーダーの処理だ。(もちろん、そのアプリやサービスの中で問題ないかは検証する必要があると思うが)。
また、最近はメモリが潤沢な場合が多いため、メモリ消費を節約するという考え方は少ないが、大規模なデータを扱う場合には、メモリの消費を工夫するだけでパブリッククラウドの料金が大幅に下がったりするケースもある。
全探索で明らかに問題ない場合にはシンプルに全探索を選択し、少しでも拘束な処理や省メモリな計算が求められる場面では、とことん効率的な実装を目指すべきだと思う。
そのためのスキルが競プロでは大いに身につく。
実装力
競プロでは、素早くバグを出さずに実装する能力も高度に求められる。
数十行程度のコードであれば、バグを出さずにものの数分で書き上げられるくらいになる必要がある。
競プロで強くなっていくためには練習が不可欠であり、相当の実装の練習をすることになる。
毎週竸プロのコンテストに出るだけでも、それなりの実装量を積み上げていけると思うし、毎日練習するのをしばらく続ければ、そのコード量はかなりになる。
プログラミングはやればやるほど上手くなると思っているので(ある程度までは)、そのための練習としても競プロはとても役に立ったと思う。
ぼくは実装はまあまあ早いほうだと思うが、それは間違いなく競プロの経験が活きていると思っている。
これらの点を見ると、それなりの量のコードを業務で書かなければいけない人にとってはどれも大事なことではないかと思う。
ただ、コンピュータサイエンスもちゃんと勉強した上で、業務経験が豊富だったりすれば、競プロは業務にはそこまで役に立たないかもしれない。
しかし、そもそも個人的には「役に立つ」かどうかだけで競プロをやるべきかどうかを語るのは、どうも賛成できない。
だってぼく個人としては、なにより「楽しいから」競プロにのめり込んだのだし、楽しんで競プロをやっていたら、その結果としてエンジニアとして大切な基礎力がいろいろ身についた、という話だから。
そんな最高の話、なかなかあってたまるかと個人的に思う次第だ。