数学科出身の競技プログラマーの道: ①始まりから今までの軌跡

こんにちは。リユナと申します。今日は簡単に、私が競技プログラミングを勉強し始めたきっかけについてご紹介したいと思います!

 

 

0. 概要

皆さんはどうやって競技プログラミングを始めましたんですか?その時の記憶はありますか?私はあります。

いつも言ってますが、実は私は数学科です。まあ電算学科も複数専攻してますが、基本的に私が考えることや問題を解くために接近する方式などは工学者よりは数学者のような考え方により近いと思います。私は、私が記憶できる限り最も遠い過去からずっと数学が好きでした。なぜかは今も分かりませんが、数学を勉強すると自然に「これは本当美しいな」って思うことが今も結構多いです。いわば天性から数学科だったと思います。

そんな私だけど、競技プログラミングは本当に大好きです。いや、実は「競技プログラミングに関連のない他の電算学の分野」に関心がないと言った方が正しいかもしれませんね。私は徹底的に「私が好きで興味を持っていることに集中する」スタイルなので、もし興味がなかったらここまで来ることもなかったでしょう。今日は私が競プロを始めた理由、好きになった理由、そして勉強してきた方法について少しずつ説明する淡々とした雰囲気の文章を書いてみようと思います。

実は勉強方法だけを書く記事を書こうとしましたが、前の部分の内容があまりにも長くなったので、記事を二つに分けて書くつもりです。 この記事の次に勉強法について書く予定です!

 

1. 始まり

私は「韓国科学技術院敷設韓国科学英才学校」という、どこかの漫画やアニメに出てきそうなとんでもない名前の高校を出ました。まあ実はそれでも、私の口では言うにはちょっと恥ずかしいですが、韓国の最難関高校の一つだと思います。韓国にも偏差値があったら多分75は軽く超えるでしょう。日本でいうと、全校生の80%が東大、京大、あるいは東工大に行くと言ったら一通り説明になると思います。

「まあ、それですごいことはわかるけど、それがどうしたの?」って思うはずですね。実は高校でプログラミングが一年生から必須科目であって、それでプログラミングに初めて接したからです。それまでは一度もプログラミングをしたことがなかったので、一つ一つprint("Hello, world!")を入力した記憶が今でも生々しいですね。ここで気づいた方も結構いらっしゃると思いますが、最初に習った言語がPythonでした。確かに直観的で学びやすかったのはよかったですね。でも競プロには弱いところがたくさんあります。これについては多分後にかく勉強方式の記事でもっと説明する予定です。

プログラムが私の意図に従って機能し、動くのが不思議で楽しかったです。 それを通じて様々な問題を解くことができました。当時はこれが試験勉強でしたが、私はむしろとても楽しかった記憶が大きいです。でも、「それ面白かったよ~」くらいに移って、その後またプログラミングをしなかったのかもしれません。

もっと本格的なきっかけは高校2年生が終わる頃にできました。 1年上の親しい先輩が競技プログラミングを当時着実にしてきて、私にも勧めました。 授業時間に簡単に学んだアルゴリズムを利用して数多くの問題を解いて、それを悩み、インターネットサイトに提出して自分の解釈が正しいかどうかを確認できるという点が本当に不思議でした。その時からBOJを始めて、ACの喜びを感じ始めました。

気が付いたら、高校3年生の時には大学入試を控えていたにもかかわらず、一日中パソコンの前に座って、BOJで問題を一生懸命解いていました。 この頃KOIの存在を初めて知ったので、遅すぎたけど、それでも一度は挑戦してみよう。 ということで、最終本選で銅賞をもらった記憶があります。

しかし当時の私の勉強方式は良く言えば「熱心に」で、悪く言えば「何も知らずにむやみに解いた」に近いでしょう。 高校3年生を卒業するまでセグ木が何なのかさえ知りませんでしたからね。当時にはsolved.acのような事もなかったし、codeforcesAtcoderの存在も知らなかったので勉強方式がめちゃくちゃでした。しかし、この時の経験は私が基本技を徹底的に固めるのに役立ち、知っている問題であれ知らない問題であれ、問題一つ一つに真剣に取り組む態度を学ぶきっかけになりました。何より、「競プロの面白さ」をしっかり学んだ時期だったので、私にとっては今でも大切な記憶です。

 

2. 大学を入学してから

もちろん当然学校の勉強や大学入試も充実してきたので、無難にKAISTに入学することができました。1年生の時に初めてICPCの存在を知り、競技プログラミング研究会で何とか誰でも捕まえてチームを作って予選に参加しました。 しかし、当時は経験があまりにも足りなかったし、実力も足りなかったので予選で凄惨に失敗して落ちましたね。でも初めてのチーム大会だったので、いい経験になりました。

この時に研究会に入ってから色んな人々と出会いました。IOIの韓国国家代表出身のやICPC WF出場経験のある人たちが並んでいて、私はその間で人々がどのように勉強してきて、何をしてきたのかを着実に追ってきました。今でもずっと感じることですが、同じ趣味を楽しむ人たちがそばにいるということは本当に大きなモチベーになると思います。

そして、この時に本当に韓国の競技プログラミング界に革新的なことが起こりました。 solved.ac がベータサービスを開始したのです。以前までめちゃくちゃに、よく分からない状態で何でも挑戦してきた私には本当に新鮮な衝撃であり、分類タグで知ることさえできなかった数多くのアルゴリズムと最適化技法を一つずつ見ながらネットを探しながら勉強しました。あと人々のティアが出てくるのも、負けず嫌い私には大きな動機付けになりました。 難しい問題をどんどん挑戦して解いてみるのがとても楽しくなりました。solved.ac がリリースされて以来、韓国の競プロerたちの実力が上向き平準化されたという話がよく聞かれますが、私は実際に多くの恩恵を受けたと思います。

二年生になってからはBOJで様々な問題を解いて、時間が合えばcodeforcesで大会を行うという形で、その前までとは違ってとても真剣に競技プログラミングの勉強を始めました。そうしながら、私の強みを確実に把握することができました。 私は基本的に数学科でしたし、大学1年生の時にすでに「韓国大学生数学競技大会」で金賞をもらうほど問題を解く実力はかなり優れていました。競プロをしながら数学的要素が入っている問題は、私が他の人に比べて優位を持って問題観察ができるという点を把握し、多分このような部分が「私にも上手くできる部分があるんだ!」と大きく動機づけされました。

また、ICPCチームを決めながらも大きな幸運が伴いました。 当時、校内上位チームの一つで規定上の問題で一人がやむを得ず抜けることになり、急いで代替人員を探さなければなりませんでした。 ところで、そのチームのメンバーの一人が上で話していた親しい学校の先輩でした! おかげで私はそのチームで数学担当を務めることができ、立派なチーム員と共にしながら実力者たちはどのように勉強して練習するのかを確実に学ぶことができました。当時はソウルRegionalで13位を獲得し、奨励賞を受賞しました。

率直に言うと、当時の私はそのチームにいるにはあまりにも実力が落ちる状態でした。 過分なほど良い機会ができて実力者たちの世界を一度味わった気分? そうだったからますます大きな目標ができて、私もその場に合う、どこかで「あたし、こう見えてもICPCの賞ももらったよ」と言うので恥ずかしくない人になるためにもっと勉強し始めました。

 

3. 休学

その途中で私に他の方に機会ができてしばらく休学をして某会社でプログラマーとしてインターン生活を体験することになりました。どうせコロナウィルスのせいで学校で正常な学生生活を送ることができないと判断されるので、この機会にいっそ他のことをしよう!とも思いました。 ちょっとだけ指摘しますと、韓国では日本と違って大学生の休学が一般的です。 最大の原因はもちろん兵役の問題であり、そのため休学自体が一般的なものと認識され兵役がかかっていなかったり、すでに解決している人たちもリフレッシュや就活、創業、その他の体験や勉強などのために休学することがかなりあります。ケースバイケースですが、少なくとも私の学校はもっとそうでしたね。

まあ、その経験については詳しく書かないと思います。多分これからも話すことはないと思います。だって、当時の私は社会に出る準備ができていなかったし、たくさんのつらいことがあって心と体の健康をかなり台無しにしました。

それで会社生活を終えても回復のためにある程度休んでから学校に復学することにしました。 まあ、それが私が年が多いのにまだ卒業してない理由にもなります。当時の私は本当に何もしないで家に横になっていてもいい状況でしたが、勉強するルーチンを蘇らせ、復学後の学校生活に備えるために競プロの練習に再び没頭しました。

当時の私はどうせ残るのが時間だったので、できるだけ色々なアルゴリズムを勉強して、どんな状況で使うのかを見るためにたくさんの問題を見て、直接実装してみたりして勉強を重ねました。 これを続ければ続けるほど、solved.ac でティアがどんどん上がって達成感が高くなりました。 codeforcesもまた始まって、当時薄橙まで上がっていましたね。(今は大会を何回か台無しにしてまた青ですよ)

実際、この時勉強したアルゴリズムの中で、今も実戦で上手に使えるほど慣れているものはそれほど多くありません。 特にチーム大会だと、いつも私よりはコードの実装が上手なチームメンバーがいたので、私がコードを書くことはそれほど多くありませんでした。しかし、私はこの期間、「どのような類型の問題でどのような方向の解釈を取っていくのか」に対する大まかな感覚を知り、「少なくとも私が確実にできることは逃さない方法」を学んだと思います。 これは、特にチーム大会で問題の解き方を話し合って進むのに大いに役立ちました。

まあそんなにだんだん時間は流れ、私はまた復学するようになりました。

 

4. 復学後から今まで

復学の頃に私は友人から「私の母校で競プロがとても上手な2人の1年生がKAISTに進学するが、ICPCチームを作る残りの1人を探している。 あなたは数学に特に強いので、もしよかったら紹介してもらえない?」という提案をいただきました。私には本当に千軍万馬のような存在で、その後の成長に大きく役立った友達に出会いました。

これがMunSongSongチームの始まりでした。

二人の後輩たちは素直に言って、競技プログラミング自体の実力は私よりはるかに優れていました。 私も休学期間中に能力を磨いて足りない水準ではなかったですが、高校の間KOIとIOIの準備をたくさんしてきた後輩たちに比べものになりませんでした。 ただ、以前まで勉強をしてきたことがあったので、私は二人が話す内容自体はかなりついてくることができました。

チーム練習を重ねながらICPCのための準備をしてきましたし、お互いがお互いの長所と短所を明確に把握しながら大会への戦略を立てていくことができました。 これについての話は以前書いたICPCのレビューでもしましたので、今は省略したいと思います。まあそれで、2022年ICPCでは7位で銅賞、そして2023年ICPCでは4位で銀賞を受賞するという素晴らしい成果を上げました。 今は本当にWF出場以外、すべてのことをやってみましたね。ただそのせいで私は今すごい競プロ悪鬼になって卒業すらできなくなりました。ww

この期間にもう一つ説明することといえば、私が高校の時から教えてきた後輩たちがいます。私は高校3年生の時、当時1年生の後輩として初めて入ってきた学生たちを対象にプログラミング科目の補充講義をしました。 最初はみんな1年生の時の私のようにプログラミングに初めて接していましたが、彼らの実力はすぐに日進月歩きました。 学期が終わる頃には、私がいたずらで出したKOI問題をBFSを習ったこともないのに、自分で考えて解くほどでしたよ。 私はこの後輩たちと早く仲良くなれたし、弟子(?)にして競技プログラミングを教えながら親しくしてきました。

彼らが奇跡的に全部入試にも成功して、みんなKAISTに来ました。まあ実は入学はもっと前でしたが、コロナウィルスのせいで、あと私は休学してたから学校で会えませんでしたね。私は親しい後輩たちと大学でまた会えて本当に嬉しかったし、また一緒に競プロを一生懸命勉強しました。 高校生の時の私とは比べ物にならないほど私も実力が伸びていたので、私ももっと体系的なカリキュラムで徹底的に教えることができました。 いつの間にかその後輩たちは私にとって数学がそうだったように、自分たちが好きな分野を一つずつ探してその部分を自ら勉強し始めました。 今では、それらの分野に関しては、私よりもはるかに優れた実力を持つ素晴らしい競プロerになりました。

そして今になっては、本当に偶然のきっかけによって日本の競プロerたちともつながるようになって、もっと多くの人たちと交流したくてこのように日本語で記事を書いていますね。 他の国の学生たちがどのように勉強し、悩みながら競プロをするかを学ぶ機会は本当に貴重だと思うので、私はこれもまた私にとって大きな転換点になったと思います。そして私も、皆さんにできるだけ私が経験してきた話をしたいです!

 

5. 終えて

実は私が競プロをしてきた経験、その過程で会った人々、してきた悩みに対する話はここに全部込めないほどはるかに深いです。まあ、誰もが自分だけの素敵な話を持っているものですから。私も私のすべての経験を伝えることができなくても、これを通じて少しでも競プロを楽しむ一人がどんな感じで今までやってきたのかを知ることができれば、私としてはこの上なく嬉しいと思います。

結局、私が競プロを長い間楽しんできた原動力は、「知らないことを知った時の喜び」、「だんだん実力が上がっていくのが感じられる時の達成感」、「負けず嫌いの競争心」、そして何よりも「好きなことを一緒に分かち合い競争しながら助け合える人たち」がいるからだと思います。「競プロ無用論」や「早くやめとくほうがいいな」っていうことも競プロのコミュニティなら両国共通でよく出てくる話ですね。だけど、私にとってはこれは楽しい余興や趣味のような感じで、ある意味ゲームのような存在だと思います。皆が考えるところはそれぞれ違うでしょうし、私の意見に同意しない方も本当に多いと思いますが、まあ、すべての人が楽しむ方法はそれぞれですからね。

少なくとも私は、私がこれをしながら感じる楽しさが減り、疲れだけが大きくなるという気がするまでは、大会に出られるかどうか、それが実際に学問やプログラマーとしての活動に役に立つかどうか、地道に少しずつ競プロをしていくと思います。そして、私の達成感ややりがいを、誰かと少しずつ分かち合えたら、それもまたとても嬉しいと思います!

次の記事では、私の話よりは、もう少し具体的に私が考える競プロの勉強法について説明します。 読んでくださってありがとうございます!