2022年の振り返りと競プロと私
はじめに
2022年は個人的にそれなりの転機になったような気がするので、色々振り返っておきたい。Twitterで今年を振り返っている人がいて、自分もやりたいと思ったがTwitterでは文字数が全く足りない。
長文を書く場合は最近は主にQiitaを使っていたが、今回のは技術記事ではないので適切ではない。なので存在をほぼ忘れていたはてなブログのアカウントを引っ張り出してきた次第である。
雑なまとめ
- 競プロを始めて本当に良かった
Kotlinはいいぞブレワイが面白かったアトリエシリーズが面白かった。特にフィリスとリディスーリディスーのプラフタはかわいいよ
競プロ観点での時系列での振り返り
まずは競プロに絞らずに時系列で一通り振り返ってみたのだが、長くなりすぎてしまった。今年の大きな出来事としてはやはり競プロを始めたことで、現在の最大関心事も競プロなので、競プロに関係ない部分はできるだけカットしてお送りする。
1月
競プロはまだ始めていなかったが、自己研鑽として「勉強」ではなく実際の取り組みが何か必要なのではないか?と思っていた。以前、通信制大学に入ってITを学び直すなどしたことがあったが、正直何も身につかなかった。
自分は机上の勉強ではなく実践が伴わないと身につけられない人間だと思った。でも何を実践すればいいのだろうか…?
2月
競プロはまだ始めていなかったが、ゲーム以外にも何か他に趣味が欲しいと思っていた。交流が発生するようなものであればなお良いと。
3月
会社の人がAtCoderをやっていることがわかった。ちょっと楽しそうだなと思った。以前からAtCoderは知っていたし、そもそも数年前に参加していたこともあるが、その頃に挫折しているので苦い思い出となっていた。
そのため、ただちに自分もやってみようとは思わなかった。しかし、挫折した悔しさと、本当はやりたいという気持ちが残っていたので、参加を考え始める。
4月
自己研鑽として「勉強」ではなく実際の取り組みが何か必要なのではないか?ってもう一度思った。
何かを勉強するとき、いつか使うだろうと思いながらやっていた。いつかっていつだよ。今必要なことをやらないと身につかないよ。
何かを勉強したとして、その時は「今度仕事で必要になったら使おう」と思うけど、実際にはその機会は訪れないか、もしくは訪れたときにはもう忘れていたりする。
身につけるために実践の機会を意図的に作るのも重要なんだけど、そもそも日常的にプログラミングしているのであれば、学んだことを素早く取り入れて試すことができる。勉強のための実践って結局勉強の延長なので本当の意味での実践ではなく、定着具合はイマイチ。勉強したことを勉強用以外のプログラミングのために取り入れたらそれは本当の実践なので、定着が段違いになる。なので、勉強以外で日常的にプログラミングすることが重要、という感じ。
勉強したことを定着させるために無理やりなんか実践するのではなく、そもそも普段プログラミングをしていて、それに役立つことを勉強する、ならいいのかもしれない。
では何を実践するのか、なんですよね。ここがネックだった。何も思いつかない。作りたいものなんて別にない…
5月
Pythonの勉強のためにCheckiOというサイトで問題を解いていた。決められた制約に沿った値が入力されるので、それについて何らかの処理をして出力する。その出力が正しければOKというものである。
あれ?これって競プロじゃね?って気づいた。ただ自分が知る限りでは、コンテストのようなものはなかったと思う。
どうせならコンテストがあるAtCoderのほうがよくない?と思い、AtCoderに復帰することを決める。早速C++の環境構築をした。(Pythonじゃないんかい)
6月
- 自己研鑽として「勉強」ではなく実際の取り組みが何か必要なのではないか?
- 自分は机上の勉強ではなく実践が伴わないと身につけられない人間だと思った。でも何を実践すればいいのだろうか…?
- 何か他に趣味が欲しいと思っていた。交流が発生するようなものであればなお良い
- 勉強したことを定着させるために無理やりなんか実践するのではなく、そもそも普段プログラミングをしていて、それに役立つことを勉強する、ならいいのかもしれない。
- では何を実践するのか、なんですよね。ここがネックだった。何も思いつかない。作りたいものなんて別にない…
妙な前フリをしていたけど、要するに競プロでよくない??って思った。
さらに、アルゴリズムやデータ構造、数学についてはずっとやらなきゃいけないと思っていた。いい機会になるはずだと思った。
競プロは、すごく自分の求めていたことにガッチリはまる感じがあった。
そういうわけで6/4、ABC254で久々にコンテストに参加!
記念すべき?復帰戦の結果は2完。しかも遅い。まあそうだよね…
C問題は過去にも(簡単な回を除き)解けなかったので、鬼門になるのはわかっていた。なので当然そうなると受け入れて、焦らず、他の人と比較せず、長期的に取り組むと決めていた。落ち着いて力をつけていけばいいと思った。
実力とは無理やりつけるものではなく、長期的に取り組んでいるうちに気づいたらついているものだと思っていたので、当面はただ参加し続けることだけを目標とした。
コンテストに参加するだけでなく過去問もちまちま埋めていたが、A問題でWAを出すなどして凹んでいた。さすがにこれはいかんでしょと思った。自分がこんなに実力がなかったとは…
7月
この頃から、Zennで競プロの記録をつけるようになった。C問題は解けないが、解説を見て目から鱗というか、すごく新鮮に思って記録をしたいと思った。
Cが全然解けずに心が折れるかと思いきや、むしろやる気に満ちていた。
自己研鑽として何をしていけばいいのかということはずっと葛藤があったが、当面は競プロに力を入れるってことでいいのではないかと自分の中で結論が出た。自己研鑽としては競プロだけしかやらないのは十分ではないのだが、競プロ自体の有用性には確信を持った。
8月
引き続き競プロについて自分なりに分析を続けてきた。これについては別の記事でも書いたのだが、自分はプログラミングでものづくりをしたいのではなく、ただ純粋にプログラミングをしたい、自分が書いた通りにコンピュータが動くのを見て楽しいと思いたい、それだけなのだと気づいた。
プログラミングはものづくりだと表面的には思っていたので、プログラミングしたいはずなのにプログラミングしたくない???と混乱していたが、このように整理すればすっきりした。ものづくりではないプログラミングも存在するし、自分がやりたいのはそれだった。つまり競プロですね。
ものづくりする仕事に就いているのでこのような思考になっているのは良いことではないが、しょうがない。嘘はつけない。それに、競プロで鍛えられる力はものづくりにも必要ではあるので問題はないと考える。
そのように思ったのでコツコツと精進を続けていた。
いろいろなC問題を解説ACする中で、数学ができないことが致命的なボトルネックになっていると痛感せざるを得なかった。なので、数学の勉強も始めることに。 本当に最初からやり直したかったので、数学以前に算数から始めた。
さすがにそこまでは…と思ってはいたのだが、やってみたら簡単な算数の計算でも脳が悲鳴をあげることがわかったし、しょうもない計算ミスを連発することがわかったので、お恥ずかしながら算数からのやり直しで正解だった…
こうなってくると、競プロや数学が有益かどうかという以前に、このレベルで躓いている自分を許せないという気持ちのほうが強くなってきた。ちょっとしたコーナーケースを見落としてWAを出す自分、稚拙な全探索しか思いつかなくてTLEを出す自分、小学生レベルの計算で脳が悲鳴をあげる自分…
しかし、絶望はしない。むしろ、自分のダメな点が明らかになってよかったと思う。競プロは本当に自分のダメな点を容赦なく炙り出してくれる。これは強がりではなく、本当にありがたいことだと思った。
なお、これまではC++で競プロしていたが、この辺りからKotlinに乗り換えている。C++は残念ながら自分にとっては書きやすい言語ではなく、仕事で使っていて書き慣れているKotlinを使ってみることに。もし必要性を痛感することがあればまたC++に戻ればいいかなって。
仕事で一番長く使ってきたのはJavaなのでそれも選択肢だが、Kotlinのほうが簡潔に書けるのでそちらに流れている。
9月
ようやく入茶を果たしたのがこの月。レーティングには執着しておらず、早く入茶したいなーとも実はそこまで思っていないつもりだったのだが、結局入茶記事で長文ポエムを書いてしまったのでやっぱり嬉しかったのかも。
入茶した回はCが解けずにAB早解きで茶パフォが出たので、まだまだだなーとは思った。しかし、十分な実力を得たとは到底思えないまでも、少なくとも前進はしていることは明確になったのでその点が嬉しかったのだろう。1度(いや実は2度)挫折していることを一応は克服したのだと。
まだまだC問題は解けないけど、C問題を安定して解けるようになりたいというのがけっこういい感じの目標になっていたのかも。簡単には達成できないが、不可能というわけではなく、頑張ればいけそうというのがちょうどいい塩梅だった気がする。
過去問だと解けるC問題も出てきたので、それなりに成果は出始めていた。いよいよ楽しくなってきたという感じ。
その一方で、モチベをレーティングに依存することの危険性についても考えていた。レーティングは変動するので、下がり続けて灰落ちも普通にあり得る。そうなっても自分はモチベを保てるのか?
競技なので競争要素がモチベになるのは普通だし、それは人それぞれの考えがあるので他の人に対して口を出すようなことではない。ただ、自分としてはレーティングのようなふわふわ変動するものにモチベを左右されたくないと思った。レーティングが下がったけど問題が解けてうれしい、解けなかった問題の解説を見て新たな知識を得てうれしい、くらいのほうが生きやすいだろうと。
まあレーティングを一切気にしないというのは現実的には無理なんだけど、解けた!の嬉しさのほうをできるだけ重視したいと思った。
10月
いよいよコンテスト本番でC問題をACするという実績を残した。まあそれ以前にもCとは思えないくらい簡単だったとか、実は理解してないけどググったら解法を見つけちゃったとかはあったのだが、その回は正真正銘実力で難しい問題を解けた。しかも緑diffだった。これは本当に嬉しい。そして、解ける問題を増やしてこういう嬉しさをもっと多く感じたいと思った。
まあ「解けて嬉しい」とは「解けなかったら嬉しくない」に繋がるかもしれないので、もう一歩思考を進める必要がある。正直、成長という観点だと解けた時より解けなかった時のほうが成長すると思う。なので、解けたら嬉しいのでOK、解けなかったら成長するのでOK。どう転んでもお得。これでいこう。
それと、ようやくDPの勉強も始めた。DPで解く問題の解説を何問か見たがサッパリ理解できず。事前知識を先に勉強しないと解説を理解すらできない問題もあるんだなあと思った。
この頃になるとTwitterでの交流も増えたし、マシュマロも飛んでくるようになったので嬉しかった。
11月
ABCで初めての4完を達成したのがこの月。Dにしては簡単だったといえばそうだけど、普段よりも順位が高めに出たのでやっぱり嬉しい。成果を実感できるとほんとに嬉しいね。
ただ、何でもうまくいっているわけではなく、また一つ重要な気づきを得てしまった。それは、自分は今までずっと、足りない考察力と実装力を動作確認しまくることでカバーしてきたんだなということ。つまり一応それらしく実装はするが、普通にバグがある。動作確認によってそれに気づく。直す。また動作確認するがまだバグがある。直す…を繰り返すみたいな。それって、単純にプログラミングがちゃんとできてなくない…?って。
実務でも今思えばそんな感じだったけど、実務だと動作確認は比較的しやすいので、動作確認スキルが高いのであれば一応問題はなかった。画面の実装とかなら、思いつく限り全ての操作方法や入力値を全部試せばいい。私は全探索脳なので、これは試さなくていいよね?とかはあんまり思わず、ほんとに全部試してきた。それでバグも見つけてきた。文字通り、動作確認しまくることでカバーしてきた。
しかし、競プロではなかなかそうはいかない。問題にもよるが、入力が複雑な場合はサンプルを試す以外の動作確認が面倒。だがサンプルが親切とは限らないので、十分に動作確認するのであれば自分で入力値を用意しないといけない。しかし、それに対する正しい出力は自分で計算しないといけないので得るのが難しい。それ以前に、どのような入力値を試すべきなのかの判断が容易ではない。
愚直実装もして結果を照合するテクニックもあり、自分も何度かお世話になっているけど、愚直実装すら大変である問題に対しては使えない。
そもそも、できるだけ早く提出してACを得る競技なので、動作確認に多くの時間を割くわけにはいかない。なので、足りない考察力と実装力を動作確認でカバーするというのは競プロでは通用しづらい。
十分な動作確認がなくても正しい実装ができるなんて化け物かと思ったりもしたが、実際それなりのレーティングの人はみんなやってるわけなので、やはりこれは普通に自分の弱点と捉えるべきなんだろうなあ…
これは実は私としては本当に衝撃的な気づきだった。私は他の人よりバグを見つけるのが得意だったと思う。それはバグ検出件数という形で数値化でき、他の人の数値と比較できるので、おそらく勘違いではない。その理由は何かというと、おそらくだが私が全探索脳だからだと思う。普通の人ならこれはテストしなくていいだろうと判断するようなことも、めんどくさがってやらないようなことも愚直に全部テストしてきたから。
こいつめっちゃバグ見つけてくれるやんって評価されることもあった。全探索脳が私の武器だった。それが…まさか通用しないとは……
むしろ、全探索脳による動作確認でカバーできてしまうが故に考察力や実装力が十分に育たなかったのかもしれない。自分の武器だったはずのものが、むしろ仇となった形。
自分にこのような弱点があったとは。また競プロが一つ自分に気づきを与えてくれた。ありがたい。そして、この弱点はきっと競プロを続けることで改善できるのだろうと思った。
まあ、ここまでくると自分は普通にプログラミングの能力が低いと認めざるを得なかった。気づきを得られたのはありがたいが、現実が残酷すぎてちょっとメンタルに来てしまったところもあった。
こういう時は「頑張らないと」と思ってしまうけど、頑張りすぎるとそれはそれでメンタルに来て逆効果になるので、頑張らないことも考えないといけない。頑張ることも頑張らないこともどちらも重要。変な話頑張るのは簡単で、頑張らないほうが実は難しい。頑張らないことを頑張れって言われたことがある。だいぶ身にしみてわかった。
なのでこの辺りから、休日はあんまり頑張らずにゲームをやることにしている。休日は、休むための日なんだよ…
とはいえ、他の人が頑張っている時に自分はゲームをするというのはそれはそれで精神的な負荷がある。休むのは必要だけど、休みすぎて成果が十分に出ないと、それはそれで問題。頑張り過ぎたらダメだけど、頑張らなさ過ぎるのもダメ。む、難しい…
結果単体で捉えず、直近の精進具合も含めて考えたらいいのかもしれない。結果は出なかったとしても、最近はブレワイが楽しすぎてあんまり精進できてなかったので当然である、みたいに冷静に判断できればいいのかと。 この辺は今も試行錯誤を続けている。
この時期の精進の内容としては、グラフの勉強をしていた。これも解説を見ただけだといまいち理解しきれなくて、一から勉強する必要があると思った。
こういう勉強の仕方は良いと思っていて、明確な目的はないけどなんとなくグラフをやるかー、というのよりも、この問題の解説を理解するためにグラフをやる、と明確な目的があるほうが吸収しやすいと思った。
こういった明確な目的を得るにはやはり日々の具体的な取り組みが必要で、今は競プロが自分にとってそういう存在になっている。
なお、DPやグラフの勉強ではアルゴ式のお世話になった。アルゴ式の教育的な問題は自分がよくわかっていないものを理解するための訓練としてはとても良い。
あとは、算数の勉強は終わって中学数学の勉強に進んだのがこの頃。先は長いけど、継続していけば着実に力はつくはず。
12月
ABCで久々に灰パフォを出したりして、焦りを感じるなどした。先月に引き続き、ちょっとメンタルに来ていた。メンタルケアは重要。
ここのところは、ABCでC問題が簡単な回が続いているので、早解き勝負の側面が強くなっている。なので早解き力も鍛えようと思ってバチャにも少しだけ参加するようになってきた。成果を実感するには至っていないのでまだまだこれから。
気持ちとしては、C問題は歯ごたえがあるほうがありがたいとは思う。解けて当然の問題しか解けなくてコンテスト終了よりは、それなりに難しい問題を通すことができて満足感を得てからコンテスト終了のほうが当然楽しい。
まあでも仕方がない。それならCまで高速に解けるようにするか、Dも解けるようにするかのどちらかで考えるしか。
年内最後のABCでは、D問題がそこまで難しくなかったはずなのに解けなくて悔しい思いをした。年末は消化不良で終わってしまったので、もう少し頑張りたい。
DPを勉強するとかグラフを勉強するとかもいいけど、やはり問題を解くのが一番とも思ったので、直近だとABCのC問題の過去問をまた解くようにしている。アルゴ式の教育的な問題も良いのだが、アルゴ式だとどういうアルゴリズムで解ける問題なのかわかっている状態で解くわけだし、そもそも理解に導くことを目的として作問されていると思われるので、コンテスト用に作問された問題とは趣が異なると思った。両方やるのがいいけど、最近はアルゴ式に偏っていたのでABCの問題のほうに少し寄せた。
その回のD問題については、テストケースに制約違反があって部分Unratedになっていた。自分のレーティングとしては全体Unratedになるほうが冷えなくて済むことが想像できた(実際そうだった)が、全体Unratedになってくれーとかは全然思わなかった。自分は意外とレーティングに執着がないことがわかって少し安心した。
今月はTwitterで初めてリプを交わし合う人が増えたり、リアルでエンカする人もいて交流が促進できた。期待以上に交流が生まれたと思うので嬉しい。
2023年の目標など
入緑するみたいなそういう目標は立てない。年末は不完全燃焼になってしまったので、まずは早めにまた満足のいく結果を出せるようにしたい。
取り組んでいれば相応に強くなるやろ(適当)って思っているので、とにかく継続したい。やめてしまうことがないようにしたい。なので他にも目標があるとしたら、来年の年末時点でもまだコンテストに参加し続けていることですかね。
参加を継続さえするなら、自ずと精進もするだろうし、数学の勉強も進んでいるだろうし。そんな感じでよいと思う。
競プロは自分の弱点を容赦なく炙り出してくれたけど、それらもおそらく競プロを続けていれば改善されていくでしょう。焦らずコツコツと。