verilog書く人

自称ASIC設計者です。どなたかkaggle一緒に出ましょう。

AtCoderで黄色コーダーになりました

f:id:segafreder:20210120222820p:plain
rate

会社員やりながら色を上げるのは大変だと思いました。しかし、レート確定の瞬間は全てが報われる爽快感がありました。

継続してよかったです。

以下ではこれから黄色を目指す人の助けになるかもしれないことをつらつらと書いていきます。ポエム多めです。

Difficulty pies

f:id:segafreder:20210120225244p:plain
pi

他の黄色昇格者より多めに解いてる方かもしれません。才能なさすぎか?

精進

精進には2つの目的があります。それは「今の自分の実力で解けない高度な問題を解けるようにすること」と「解ける問題をより速く、正確に解けるようにすること」です。

どちらがボトルネックか認識しておくとレートがあがりやすいです。

私の場合、時間が足りなかったりペナルティ数が多くて順位を下げたりすることが多いなと感じていて、ここ半年では後者がボトルネックでした。

なので、速度を上げるために60-90minのバチャを週4くらいでやることでレートが上昇し始めました。

「自分の実力で解けない問題を解けるようにする」ためのトレーニン

基本的にはAtCoder Problemsでレコメンドされる問題に挑戦して、解けなかったら解説を読むというのをやることになるのですが、いくつかポイントを上げておきます。

  • yukicoder、有志コンも解く

案外yukicoderの過去問に近い問題がAtCoderに出たりするので、解いておくとよいです。

黄色コーダーを目指すなら★2.5-3あたりがちょうどいいでしょうか?3でも難しすぎる問題がある印象です。

あとはFavがある程度ついている問題を選んでいました。

  • 黄色コーダーになると○○法みたいなアルゴリズムの種類は要求としてそこまで増えないが、細かい知識の要求は増える

頂点数Nの単純で連結なグラフにN-1本辺があるときそれは木であるとか、素数には原始根が存在するとか、DFS木の後退辺がどーたらとか、そういった細かい性質は知識として増やしていく必要があります。

蟻本のコラムとかが元ネタの問題も見受けられますよね。蟻本は隅まで読むと良いです。

  • なぜ解けなかったのか、を考える

例えば逆から考えるとか、数え上げや期待ではある要素についてコントリビュートを足し上げるとか、そういう考察法の典型が身についてなかったり、知識が足りなかったりといった原因を特定して対策します。

(解法が天才閃き前提で悩ましいときもありますが、、)

  • 解法の正当性も押さえる

厳密な証明とまではいかないまでも、気持ち正当性を確かめるようにしています。

そうしないとコンテスト中で誤った解法を出してWAをもらったり、逆に正しい解法でも踏み出せなかったりします。

とはいえ、コンテスト中は未証明でもいくっきゃない!えいや!で提出していることは結構あるんですが、コンテスト後に解説見て解法の正当性を確認して以後のコンテストで精度を上げられるようにします。

「解ける問題をより速く、正確に解けるようにする」ためのトレーニン

速く、精度良く問題を解くためには

  • 典型の考察ステップを減らす
  • よく使うコードをIDEのTemplateに登録したり、ライブラリにする
  • 言語に習熟する
  • 自分のミスした場所を記録し、同じミスを犯さないようにする
  • シンプルでバグりようのない実装方針を立てる

というところを大事にしていました。

これらの要素を意識しつつ、バチャを繰り返すことで速度と正確性は上がっていきます。

私は解いたことがある問題でも構わずバチャしていました。以前の自分の実装よりシンプルなものができてて、成長を感じられたりします。

また、バチャを繰り返すことでコンテストが日常となり、本番コンテスト中での変な力み・緊張が取れていきます。

最後の要素の「シンプルでバグりようのない実装方針を立てる」スキルは他の人の提出を読むことによってより効率よく磨くことができます。

AtCoderの提出コードは言語ごとにコード長でソートすることができるので、それで短いコードを探してなぜ短いのか考えてみたり、デキる人の提出を読んだりします。

f:id:segafreder:20210120223222p:plain
s

思うに競技プログラミングのよいところの一つは「皆が同じ問題を解いているので、上級者と自分の実装スキルの差が顕著になる」ことです。

普通プログラミングというのは車輪の再発明は避けられ、同じタスクをやるためのコードは一度しか書かれないのですが、 競プロでは何千人もの人が同じタスクを解いているので、一番うまい実装方針を参考にすれば確実に実装スキルを向上させることができます。

私自身「ACすればよい」と思っている時期がありましたが、これに気づいてからは「よりよい状態(シンプルな実装方針、エスパーよりなるべく正当性がわかっている)でACする」ということを意識しています。

コンディション

本番コンテストでは限られた時間で集中力を発揮する必要があり、コンディションは結果に影響します。

睡眠・食事が基本です。

睡眠

睡眠は規則的に、ということが大事なんですがなかなか寝付けないときもあります。

  • 午後にカフェインを取らない
  • 牛乳を飲む
  • 寝る前はなるべくディスプレイを見ない。ディスプレイの輝度を下げる。ダークモードを使う。

などを試すといいかもしれません。

寝る2-3時間前はディスプレイを見ないのが良いとされますが、会社員で平日も競プロの練習をやりたいとなるとなかなかそうもいきません。

コンテスト前日は早めに精進を切り上げる、当日昼寝する、ということを気にしています。

食事

食事はやはり栄養バランスということになると思うんですが、集中力を上げるとされるカルシウムや免疫力が上がるとされるビタミンDを取るようにしています。

後者は風邪を引くと練習の効率が下がるためです。COVID-19を防ぐという説もあります。

COVID-19

コロナにかかると競プロどころじゃなくなるので、感染対策をします。

黄色コーダーになる前にコロナにかかると「まだ私は黄色コーダーになれてないのに」という怨念の中で死ぬことになるかもしれないと思い、やれる対策はやってました(リモートワーク、手洗い、マスク)。

(黄色になってからも対策はしています。)

モチベーション

精進が楽しい間は問題ないんですが、そういうときばかりでもなかったりします。

競技プログラミングをどう位置づけるか?

色変はわかりやすい目標ではありますがそれだけが全てでもないと思います。

一緒に競い合える人がいて楽しいとか、解けない問題が解けるようになって楽しいとか、プログラミングがうまくなりたいとか。

色変する間隔は段々減っていくので、他の目的も見出してみるといいのではないでしょうか。

レートが下がったとき

レートが下がるとモチベーションが下がりそうになりますが、「レートが下がったからといって、プログラミングが下手になったわけではない」というのは言っておきたいです。

ここ一年の間でも以前はもっとdifficultyが高かったような問題が多数の人に解かれるようになっています。

すると、自分の実力が変動していなかったとしても、周りのレベルの上昇によってレートが下がることがあります。

私はプログラミングがうまくなりたくて競プロをやっているので、レートの下落によってしょげることはあれど、下手になってるわけではないと自分に言い聞かせることでモチベーションを維持していました。

レートが下がってもあまり自己否定しないでください。そもそもコンテストに参加した時点で参加してない人より進んでいるはずです。つまり、参加した=勝利です。

周囲から刺激をもらう

周りの同格~格上の競プロerから刺激を受けて高まったりします。

私の場合プロゲーマーのウメハラさんが喋ってる動画を見るとモチベーションが上がったりします。

でも一ヶ月に一回くらい「もうプログラミングできない」と思っているときもあります。

そういったものはモチベーションの低下というよりは疲労なので、Youtubeをみたりゲームしたりして、疲労回復を待ちました。

おまけ、競技プログラミングは役に立つのか?

「高度な問題を解けるようにすること」と「解ける問題をより速く、正確に解けるようにすること」が精進の目的であると言いました。

で、「解ける問題をより速く、正確に解けるようにする」スキルは常時発動型の能力のようなもので、コーディングの仕事についている限り常に役立ちます。

ソフトウェアの世界は競争が激しいので実装速度はビジネスの成否に関わる要因になりえますし、バグばかりで頓挫したプロジェクトも多く実装精度もまたソフトウェアを使ったビジネスの重要な因子になりえるでしょう。

一方「高度な問題が解ける」はどうでしょうか?

黄色になるために解けるようになった問題を解く中で、業務でも同じ方法で計算量を落とせそうだなと思ったことはほとんどありません。

仕事でプログラミングの高速化をすることはありますが、オーダーを落とすと言うよりはスレッドを増やしたり、GPGPUしたり、定数倍削減をしたりしていることが多いです。

ただ、高速化に必要な高度なアルゴリズムを書いているうちに複雑なロジックに慣れ、仕事で扱っているプログラムに対する心のハードルが下がったように感じます。

考察中のノートの記述量が減っていき、頭の中で「ここはこれでできるから…」というようにロジックをハンドリングできるメモリ容量が増設された気もします。(個人の感想です。)

また、すぐに役立つとわかるものよりも、後々になって大きい役割を果たすものもキャリアにおいてはあるかなと思います。

例えば物理学の博士が機械学習のフィールドで活躍していたりしますよね。

彼らも素粒子物理学の道具である複雑な線形代数などを扱っているとき、必ずしもその後のキャリアの中で機械学習の文脈で役に立つなんて考えてなかったんじゃないかなと思います。

ジョブズの点と点を線でつなぐという有名なスピーチもありますね。今すぐ役立つもの以外をインプットするのもきっと悪くはありません。

それにエンジニアを続けている以上、競技プログラミングの中で自分の能力の限界にあるような難問に何度も挑んだ経験というのはなんらかの形で役に立つのではないかなと。

だから、競プロは業務プログラミングに役に立つ要素は含んでいると考えます。ただそれは100%ではありませんし、色が上がるにつれて濃度が減っていくかもしれません。

また、役に立つかもしれないものは沢山あるので、競プロが楽しい・有用だと思う人が競プロで上を目指せば良いです。