数学得意じゃない系の社会人エンジニアに競プロとAtCoderを全力で布教したい。あるいは競プロのよくある誤解と楽しむコツ

このエントリは元々Qiitaに投稿したものの移植です。

このエントリはCompetitive Programming (1) Advent Calendar 2019 4日目のエントリで、バーチャル幼女プログラマーきりみんちゃんが書いています。 きりみんちゃんはVTuberとしてAtCoderの過去問を解く配信をしたりしています。

競プロ、しっていますか?

さて、みなさんは競技プログラミング/プログラミングコンテストというものをご存知でしょうか。 かなり昔から行われているものではあるので、存在は知っているという方が多いかもしれません。

競技プログラミングをざっくり説明すると、期待される入力と出力が定義された問題が出題され、それをコーディングによって解き用意された自動テストを通すまでの速度などを競うコンテストです。

最近じわじわと流行ってきている

この競技プログラミングというコンテンツ、最近じわじわとブームの兆しが来ています。 もしかしたらそう言われてもあまりピンと来ないかもしれません。 実際、自分もAndroidエンジニアとしてWeb業界で仕事や交流をしていて競技プログラミングの話題を聞くことはあまりありませんでした。

自分の観測する限りでは、今特に競技プログラミングが流行っているのは「数学が好きな理系の大学生」の界隈です。 きりみんちゃんの配信を見てくれたりフォローしてくれる人も大学生が多いですし、職場でもインターン生などでは競プロをやっているという人はかなり多いようです。

なぜ学生に競プロが流行っているのか

学生の間で競プロ、特にAtCoder(後述します)がウケている理由はいろいろあると思いますが、主に次のような理由が考えられるかなと思っています。

・順位やレートなどがあり知的スポーツ(ゲーム)として面白い
・数学問題の経験や知識がアドバンテージになりやすい
・数学やパズル、将棋などが好きでとても強い人達が集まるコミュニティが形成されている
・情報工学系の学科であれば授業の内容と重なるところがある
・プログラミングスキルとして必要とされるのは純粋なコーディングに限られるためプログラミング初心者でもハードルが低い
・機械学習の台頭などで数学/アルゴリズムに関するコーディングスキルに関心が集まっている

このような背景があり、主にとても優秀な学生の間で競技プログラミングが遊びと力試し、実益の3つを兼ねた場として流行っているようです。

社会人Webエンジニアの間では?

これはその人の技術領域などによるので一概には言えないとは思いますが、一般的な社会人Webエンジニアの間ではまだまだ認知度が低く、やっているのはやはり元々かなり数学やアルゴリズムが好きなタイプの人に限られているように見受けられます。

これにもいろいろな理由があると思いますが、次のような理由から社会人エンジニアにとって現状の競技プログラミングがハードルのやや高いものになってしまっているのではないかなと感じています。

・Webエンジニアの実務での幅広いソフトウェア開発スキルと競プロで求められるスキルに差がある
・他の学習領域に比べ実務に直結しづらく学生に比べ競プロにフォーカスした学習時間が取りにくい
・ある程度の数学の基礎知識がないとかなりディスアドバンテージがある
界隈でのレベル感の基準がかなり高く、普通のエンジニアではなかなか最低・限と言われるレベルまでたどり着けない
・純粋に学生層とクラスタが分かれていてブームが認知されていない

このあたりは参入ハードルが高めのネトゲなどと似たような状態なのかなと感じます。

Webエンジニアの間でも競プロを流行らせたいんだ

さて、ここまでは前置きというか現状の解説でした。 ここからが本題で、きりみんちゃんが競プロを半年ほどやった感想として、もっと競プロ(AtCoder)の面白さや有用性を幅広い層に布教したいと考えています。

少し長くなりますが、きりみんちゃんの体験を交えて、競プロ(AtCoder)の魅力について解説していきたいと思います。

数学知識0のきりみんちゃんがAtCoderをやった半年間

きりみんちゃんは夏の終わり頃から半年弱ほど競プロに取り組んできました。 毎週AtCoderの過去問にチャレンジする配信をしたり、毎週開催されるコンテストには必ず出場するようにしました。

そもそもAtCoderって何

はい、ここまでAtCoderについての説明がまったくありませんでした。ごめんなさい。 AtCoderとは国内最大級の競技プログラミング(プログラミングコンテスト)が出来るWebサービスです。 特徴としては、国内サービスなので問題などが全て日本語、毎週コンテストが開催されている、過去問はいつでも挑戦できる、様々なプログラミング言語に対応している、コンテストの成績によってオンラインゲームのようにレートが算出されたりするなどがあります。

他にも国内外に様々な競プロを開催しているWebサービスがありますが、とりあえず始めるならAtCoderが一番とっつきやすいかなと個人的には思います。

思ったよりも全然歯が立たなかった

きりみんちゃんは7さいのバーチャル幼女プログラマーなので、数学の教育は受けていません。 また、きりみんちゃんの保護者でありマネージャーであり知性のフォーク元でもある@kiriminも小中不登校から高卒認定で専門学校を卒業しエンジニアになったという経歴のため、まともな数学の教育はまったく受けておらず、数学の知識がないことがコンプレックスでした。

とはいえ、10年近くソフトウェアエンジニアとしてAndroidアプリなどの開発をやってきて、それほどコーディングで困ったこともないし実装の手も早い方だと思っていたので、それなりにはやれるだろうと思っていました。

下のリンクはAtCoder社長のchokudaiさんによるレートと実力の相関イメージと、別の方によるその補足記事です。

これらの記事ではレート400~800水準について「FizzBuzzは簡単に組める程度」と表現されています。
これを参考にすると「まあ自分ならこのレベルまでは一瞬だろうな」と思いますよね。

しかし実際にやってみると想像していたよりもかなり自分のイメージしていた「プログラミング」と求められる知識が異なっていて、全然問題が解けませんでした。 実際のコンテストの問題では、低難度で求められるコーディングのスキルはたしかに100点問題なら四則演算とif文、200点問題ならforループによる全件探索、300点問題ならそこに配列などのデータ構造や計算量最適化のためのテクニックがあれば解けるのですが、多くの問題ではエッセンスとして算数パズルのような要素、または素因数分解やルートのような数学知識が問題に含まれているため、そういうものに慣れていないとなかなか厳しいものがありました。 AtCoderの問題は基本的に数学パズルの考察に80%の時間を掛け、残り20%でコードを書くくらいの割合の事が多いです。 計算式さえ分かれば1行の式で書ける問題や、長くても数十行程度の問題がほとんどです。 むしろ競プロでは常に最悪のデータがテストケースに含まれるため、変に複雑な条件分岐や部分最適化などを長く書いてしまっている場合はそもそも解き方が間違っている可能性が高いです。

また、レート計算の元になるパフォーマンスの数値はコンテストでの順位とそのレートの内訳によって算出されるのですが、最近急激に新規参加者が増えている影響で以前よりも順位が団子状態になりやすくパフォーマンスが出にくくなっているようです。

(余談)AtCoderの問題は数学要素が強いのか?

ちなみにこの「AtCoderには数学が必要」という話題はなかなかデリケートで、界隈では度々議論が起こっています。 理系のハイレベルな大学受験を経験したようなタイプの人にとっては、この程度の数学要素はおそらく「算数」でしかなく、「数学が必要」というようなレベルではないという感覚のようなのですが、中学や高校前半レベルの数学やお受験で出るような算数パズルでも慣れていない者にとってはなかなか解くのに苦労してしまいます。 一方で、数学が強いけどプログラミングはそれほど慣れていないという人にとっては、むしろプログラミング要素が強すぎると感じる場合もあるようです。 (なお、より高度な問題になってくると今度はガチの数学やアルゴリズム要素が出てくるようですが、きりみんちゃんはまだその域に達していないので何もわかりません)

それでも競プロはたのしい

それでも競プロ界隈のコミュニティはあたたかく、よわよわな自分をたくさんのひとが応援してくれます。 コンテストの度にスコアが出てレートが変動していくというのは楽しいですし、レートによってランクとして色が付くのですが、それも目標を立てやすくて中毒性があります。

また、コーディングでパズルを解くというのもやはりエンジニアとしては楽しい遊びです。 時に全く分からなくて発狂しそうになることもありますが、今までの自分にはなかった発想を知ったり、様々なテクニックを学んだりするのも面白いです。

競プロ(AtCoder)は数学やアルゴリズムの学び直しに最適だと思う

自分が半年弱AtCoderに取り組んで何よりも感じたことは、AtCoderは基礎的な数学やアルゴリズムの学び直しの題材としてとても優秀だということです。

自分のように数学コンプレックスがあるエンジニアは基礎数学を学び直したいという気持ちはずっとあるものの、特に目標なく学び直すには数学という領域は範囲が広すぎて独学ではなかなか手が付けにくいのではと思います。

AtCoderではプログラミングを利用して数学の問題に触れることが出来るので、効率よく数学を学ぶことが出来ます。 きりみんちゃんはこの数ヶ月で最大公約数、最小公倍数、約数、素因数分解、平方根などの意味や計算方法について学ぶことができました。 また、それらに関係するMath系のJavaの関数や、普段あまり使用しないコレクション型の活用などについても知識もつきました。(AtCoderはKotlinにも対応している)

AtCoderの特徴として、原始的なアルゴリズム問題(ソートアルゴリズムの実装など)はほとんど出題されず、言語で実装されているクラスや関数は全て利用してパズル的な問題を解くというスタイルなので、そういう意味では実用性も高めかもしれません。 競プロをやっていると計算量についても自然に意識できるようになります。

###(余談2)競プロは実務に役立つのか これもよく界隈では議論になりやや荒れやすい話題です。 個人的な意見としては、前提として同じソフトウェアエンジニアでも業務分野によって大きくことなるので、一概には言えないかなという感じです。 自分は主にAndroidアプリの開発をしているので、実際の業務ではアルゴリズムの知識や複雑な計算式の実装力よりもSDKやフレームワーク/ライブラリなどに対する理解、UIプログラミングでの状態管理や非同期処理などを含めた設計力、UIデザインやUXなどに関する知識、そしてチーム開発でのビジネススキルやソフトスキルなどがより大きく仕事のクオリティに影響すると考えています。 なので、決して全てのエンジニアが数学やアルゴリズムに強くならなければパフォーマンスがだせないということは無いと思います。

一方で、自分はクライアントアプリケーションの実装だけではなく、もっと技術的に踏み込んだ様々な分野も理解出来るようになってエンジニアとして出来ることの幅を広げたいと思っていて、そのためにはもっと数学やアルゴリズムに強くなる必要があると考えて取り組んでいます。 また、単純にプログラミング問題の題材として大量の過去問が蓄積されているAtCoderはコーディングの速度・精度を上げる基礎トレーニングとしても効果があるのではないかなと思いますし、様々な言語に対応しているため、新しく学んでいる言語でAtCoderの問題を解いていくことで言語仕様に詳しくなれるというような活用方法もあると思います。

何よりも競プロは純粋に楽しく、エンジニアの趣味としてもっと幅広い層に定着するポテンシャルがあると思っています。

数学が得意じゃないエンジニアが競プロを楽しむための心構え

競プロが数学力に依存するかがしばし議論になったり、自分のように自認する競技プログラミング力と実際にコンテストに参加した結果に乖離がありショックを受けてしまったりするのには、根本的な競プロ(AtCoder)に対する認識がズレているという問題があると思っています。

まず前提として、AtCoderはプログラミング能力検定ではなくあくまでゲームとしてのコンテストという側面が元々あるので、レートにより能力を測ることはあくまで付属的な要素であるということがあります。 そのため、出題者は出来るだけ過去問と被らない捻った問題を出そうとする傾向があるし、そのための要素としてプログラミングと親和性の高い数学という要素が含まれることが多いです。 結果的に知識がないと解くの難しいような問題が出題されることも多く、コンテスト後の感想がやや荒れることも多いのですが、ゲームとして考えると自然なことであると思うことが出来ると思います。

とはいえ、やはりコンテストの成績によりレートという数値が算出され、その結果によってプログラミング能力の証明になると考えられている側面がある(実際にAtCoderではAtCoderの成績をアピール出来るAtCoderJobsという就活サービスもやっている)ため、どうしてもレートを上げるのにムキになってしまったり苦手な問題が出ると理不尽だと感じてしまうこともあります。(そこがゲームとして面白い部分でもある)

また、「競技プログラミング」という名前からプログラミング全般の能力を競うものだという印象を受けてしまうことも大いに影響しているのかなと思います。 実際には競プロで問われるプログラミング能力は純粋な数学的関数の実装能力であり、一方実務でのソフトウェア開発ではライフサイクルや状態管理、オブジェクト指向での設計や非同期処理、UIプログラミングやフレームワークの活用など多岐に渡り、長年それらにフォーカスして学習していたソフトウェアエンジニアとしては、「競技プログラミング」という分野で自分が素人レベルの能力であることにショックを受けてしまいやすいのではと懸念します。

そこで、数学が得意じゃないエンジニアが競プロを楽しむために意識する要素を次のようにまとめてみました。

・AtCoderのコンテストの回数は限られており、レートはかなり変動がゆっくりで、かつ最近は上がりにくくなっているため実力相当のレートになるには時間がかかると理解する
・そもそもあくまでゲーム的側面が強く様々な趣向の問題が出るため短期的な成績を気にしすぎない
・「競技プログラミング」という言葉に囚われすぎず社会人エンジニアでも競プロの世界では初心者だと自認する
・競プロ界隈には若くて非常に賢い人がゴロゴロいるのであまり比較して気に病まない

このあたりの問題はAtCoderのユーザー層が広がり正しく性質が認識されることによって緩和されていくんじゃないかなと思っています。

はじめよう!AtCoder

AtCoderはオンラインコンテストでコンパイラも内包しているため、はじめるのはとても簡単です。 まずは画面上部の「チュートリアル」リンクからサインインと練習問題をやってみましょう。
https://atcoder.jp/

練習問題が終わったら実際の過去問にチャレンジしてみましょう。 過去問を探すにはAtCoderProblemsというサービスを利用すると便利です。 https://kenkoooo.com/atcoder

ABCは「AtCoder Beginner Contest」の略で、一番オーソドックスなコンテストです。ビギナーと書かれていますが、このビギナーというのは将棋でいうところのアマチュアみたいな意味なので全ての問題が解けるようになったら達人レベルです。 プログラミング経験者であればまずは適当な回のA問題、B問題を説いてみましょう。だいたいの雰囲気がつかめると思います。 C問題からは一気に難易度があがり、競プロの知識がないと解くのがむずかしい問題も多くなります。 慣れてきたら次のような解説を読んで競プロのテクニックを学習すると一気に解ける問題が増えます。

コンテスト本番にも積極的に参加してみましょう。 AtCoderのコンテストはだいたい毎週土日どちらかの21時から開催されていて、事前に参加登録ボタンを押すだけで誰でも参加できます。参加して全然問題が解けなくても特に不利益はないと思うので、とりあえず参加してみても大丈夫です。

おわりに

乱雑な内容のエントリになっていましましたが、競プロ/AtCoderに興味を持つ人が増えてくれたらうれしいです。なおより詳しく解説したガイドブック同人誌を電子書籍として販売しています。

きりみんちゃんはYouTubeで競技プログラミングやエンジニアに関する配信や動画投稿を行っています。 もしよかったらのぞいてみてください。 


この記事が気に入ったらサポートをしてみませんか?