やおよろず

ゆるふわな内容を書いても良い。と言うか何でも良い。そんな自由度の高いブログをめざします。

入水した元青コーダーの自己分析

この記事は サステナブルなぴょこりんクラスタ Advent Calendar 2023 の為に書いたものです。

初めに

競技プログラミングってあるじゃないですか。
僕が競技プログラミングの話をアドベントカレンダーでするのは実は2018年の初参加時同年最後の記事 ぶりで、 もはや忘れてしまった人もいるような気がするのですが、僕は一応細々と競技プログラマーを続けてはいます。

続けてはいるものの、近年では競技プログラミング以外にやりたいことも増え、
以前のように「休日はひたすら家にこもって過去問を解くぞ!」みたいな熱もなく、
以前は毎週末参加していた AtCoder のコンテストも、
今では気が向けいたら参加して結果に一喜一憂する程度の日々が続いていました。 *1

そんな調子では当然のように実力やレートが向上するはずもないわけですが、
その結果としまして…

ついに青コーダーから水色コーダーに格落ちと相成りました*2

一般的には、水色コーダーというのは決して低レベルではなく、
緑コーダーから水色コーダーに挙がることを「入水した」と喜ぶブログは結構あったりします。

しかしその一方で、青コーダーを長らく維持しており、
全盛期には黄色も目指していた自分といたしましては、この変化はなかなかに悔しいものでした。

まぁ、そもそも鍛錬が足りていないのですから、遅かれ早かれこうなっていたことでしょう。
ただ一つだけ言い訳じみたことを言っておくと、
ブランクが空いた際には実装に手間取ることこそあれ、
力が衰えてきたな…という感触があるかというと、あまりそういう感じはしないんですよね。

どちらかというと、最近の AtCoder をやっている感触というのは、
「自分の中で『まぁこんなもんか…』と思った成績でもレートが落ちる。青コーダー維持が滅茶苦茶しんどい」
という感じでした。

「昔の青コーダーならこのくらいで良かったよね」という水準が許されなくなってきた感じです。

もっとも、全体的な競技レベルが上がってきてることは一般的な感触として喜ぶべきできごとですし、
変化についていけないのは時代に取り残されるおじさん然としてなかなか悲しい話ですが。
練習してないからしょうがない。

とはいえ、じゃあこのままずるずるレートが落ちてしまうのもよくはない気がするので、
今回は最近参加したコンテストなどを振り返りながら、
青コーダーに今求められてるレベルについて、最近思うことをつらつらと書き連ねたいと思います

レーティングの仕組みと青コーダーの立ち位置

AtCoder と、レーティングについておさらい

たぶんこのブログを読んでる人はおおむね知っている話かとは思うのですが、念のため。

AtCoder というのは競技プログラミングのサイトの一つです。
Algorithm(答えがある問題を時間内に解くプログラムを書く) と Heuristic(答えを出すのが困難な問題で限り良い答えを出すプログラムを書く) の二部門あり、
今回話題にするのは Algorithm の方です。

毎回のコンテストの成績に応じてレートが上下し、色によって以下のような段階分けがされています。

  • TopRanker:Top300位以上。色分けのレベルを超越した殿上人
  • 赤:Rating 2800 以上
  • 橙:Rating 2400 以上
  • 黄:Rating 2000 以上
  • 青:Rating 1600 以上
  • 水:Rating 1200 以上
  • 緑:Rating 800 以上
  • 茶:Rating 400 以上
  • 灰:Rating 400 未満

今回話題にしている青コーダーはちょうど真ん中あたりになりますね。
また、一つ覚えておくとよい話としては、
毎週のように開催されている AtCoder Beginner Contest (ABC)でレートが付くのは青までで、
全員がレート変動の対象になるコンテストは AtCoder Regular contest (ARC) というもので、こちらは開催頻度を抑えめにしつつ容赦ない難易度が出てくる感じです。

細かな話は以下の方がわかりやすいかと思います。

info.atcoder.jp

つまりは青コーダーというのは ABC に Rated で参加する人の中では一番強いレベル帯のプレイヤーということになりますね。
僕は最近もっぱらABCしか参加してないので、ABCにフォーカスを絞って話をしていきます。

AtCoder ABC の問題セットの特徴

最近の ABC の問題は7問セットが多いです。問題はアルファベット表記されててA問題からG問題まである感じ。
直近3回分のコンテストを見てみると、点数配分は以下のようになります。

ABC331 ABC332 ABC333
A問題 100100100
B問題 200200200
C問題 300300300
D問題 450425400
E問題 450525450
F問題 525550550
G問題 625625625

だいたいDEF問題が点数のばらつきがありつつ、最強枠にG問題が常にいる感じですね。
100分の時間ないにこれを全問解ける人というのはRating 対象者の中では1桁人程度*3で、 G問題までたどり着くことはまれです。青コーダーの中で差がつくところは大体DEF問題のできですね。

AtCoder ABC の振り返り

直近の自分の成績

それではここで、これらコンテストの自分の結果を見てみましょう。
かっこの中の数字はコンテスト開始から解くまでにかかった時間です。

ABC331 ABC332 ABC333
A問題 〇(2:07)〇(1:55)〇(0:51)
B問題 〇(5:34)〇(6:00)〇(6:02)
C問題 〇(13:21)〇(13:24)〇(15:29)
D問題 〇(86:07)〇(34:57)〇(30:58)
E問題 〇(97:15)×〇(44:41)
F問題 ×〇(76:04)×
G問題 ×××
誤答 001
順位(Rating対象のみ) 10732411060
パフォーマンス 139118891400

というわけで現在の自分の実力は、
7問中5問くらいはコンスタントにといているけれど
6問は解けない程度ということがわかるかと思います。

AtCoder ABC の1600パフォーマンス

上の表で断りなく使いましたが「パフォーマンス」というのが、
「このコンテストの結果だけで観たらこのくらいのレートだよ」という数字を表します。
昔はこういった値は見られませんでしたが、最近はこの値が可視化されるようになって便利な話ですね。

青コーダーだったものとしては最低でもパフォーマンス1600を取りたいところですから、
直近のパフォーマンス 1600 の人の成績を調べてみます。

ABC331 ABC332 ABC333
A問題 〇(1:49)〇(10:47)〇(1:02)
B問題 〇(4:02)〇(9:01)〇(5:38)
C問題 〇(7:09)〇(6:38)〇(11:46)
D問題 〇(18:24)〇(16:57)〇(18:04)
E問題 〇(37:25)×〇(27:56)
F問題 ×××
G問題 ×××
誤答 201
順位(総合) 882751903
パフォーマンス 160016001600

これからわかる通り、1600(青コーダーのボーダー)のパフォーマンスというのは、
たいてい500点未満の問題を全部解きつつ、その実装が速いことが求められていることがわかります。

誤答は5分のペナルティなので
ABC331 では5問を47:25、 ABC332 では4問を16:57、ABC333では 5問を 32:56 以内に解ければ
青コーダーの下っ端の水準、というわけですね。

考察と個人的な課題認識

5問を50分とか35分とか4分を16分とかってさらっと言いましたが、
1問あたり10分だったり、簡単な奴に至っては4分とかのペースで解いていく必要があります。
いくらA問題は1,2分で解くもの見たいになっているとはいえ、結構なハイペースですよね。

うすうす感づいていたことなんですが、
どうも僕はこの「500点未満の問題の速解きスピード勝負」がかなり苦手っぽいんですよね。

ABC332 のように 550 点の問題まで解けるのが個人的な勝ちパターンではあるのですが、
残念ながらその精度が安定しない中、
400点台の問題だけしか解けず終わった時に速度がないから低レートというのが典型的負けパターンとなっています。
ABC331のように、400点台の問題の実装が重めのやつでバグに苦しんで次の問題にチャレンジできないこともありますしね。

こういった考察から、最近の AtCoder の青色落ちした要因を自己分析すると
「そもそも500点台の問題を解けるようにするだけでなく、基礎的な問題を素早く解く能力が足りてないのでは?」
という点を強く感じています。

もともとは AtCoder って5問セットなどで、
こういった早解きより難しめの問題にじっくり時間をかけて臨むチャンスが多かったのですが、
7問になってからは「簡単な問題はちゃんと素早く解くこと・間違えないこと」
みたいな点の要求レベルが高くなり、そう言った変化が*4自分にとっての逆風なのかな、と。

「考えすぎて計算効率の良いコード書いちゃったけど、この制約なら深く考えずに for 文ぶん回せばいいじゃん」
みたいなところで実装時間を吸われることも増えました。
(とはいえ、こういった傾向は
「与えられた制約下で最適なコードを素早く書けるのがよく、複雑な解法をかければよいという話ではない」
 ということを意図して作られているのだと思いますし、この意図自体には賛同しています)

このあたりを伸ばすにはどうしたもんか…というのはまだ模索している段階ではありますが、
直近では難しいアルゴリズムや解けなかった問題に思いをはせるだけではなく、
解けたけど時間がかかった問題にフォーカスを充てることが自分には必要なのかもな、と思っています。

(参考)AtCoder ABC の 2000パフォーマンス

参考までに黄色コーダーのボーダーを見てみましょう

ABC331 ABC332 ABC333
A問題 〇(1:50)〇(2:16)〇(0:50)
B問題 〇(4:10)〇(5:29)〇(5:25)
C問題 〇(7:46)〇(8:42)〇(9:39)
D問題 〇(36:44)〇(20:28)〇(24:11)
E問題 〇(41:52)×〇(49:34)
F問題 〇(72:24)〇(41:15)〇(71:26)
G問題 ×××
誤答 200
順位(Rating 対象) 193166190
パフォーマンス 200020012000

このように黄色パフォーマンスになると6問は解けるようでありたい感はあります。
F問題を解くのに20分-30分のペースが必要があり、結構な速度が求められそうですね。

おわりに

というわけで、最近の競技プログラミングの結果からみるに、
難しい問題を解くスキルも必要だけど、簡単な問題を早く解くスキルも学んでいった方がよさそう、という話でした。

本当は時間がかかったところの考察みたいな話を書こうと思ったんですが、時間の関係で今回は(?)ここまで。
金曜日に向けて用意してるネタが没ったら解くのに時間がかかったる問題の考察記事が載るし、
そうでなければ準備中のネタが載ると思います。

*1:TopCoderOpen や GoogleCodeJam などの大きなコンテストも終了し、熱の覚める一つの要因だった感

*2:青、とか水色、とかはレートに応じて付与される色で、競技プログラマーはこの色でレベル帯を区別しています

*3:黄色より上の人まで含めればもっといますけど

*4:とはいえこの変化があったのも随分前だったと思いますが