会社の表彰制度を作るときにAtCoderのレーティングも表彰対象にしてほしい[1]無事、表彰制度に組み込めたのですが表彰を前に転職したので私は表彰金をもらい損ねました。という話があり調べてみたら面白そうで自分も参加してみたのが2022年1月でした。そこからどっぷりハマってABC, AHCに参加する日々です。
仕事をしながら競プロを楽しんだ1年を振り返りつつこれから年を重ねていったときにどうなるんだろうか?ということも少し考えたいと思います。
自己紹介
- 高校時代は数学が得意。大学は京大(情報)で表の専門は連続最適化、裏の専門はお酒&プログラミングで当時からプログラミングは好きでした
- 仕事はデータサイエンス領域のコンサル。RやPythonを書く機会はあったものの職業プログラマというほどではなかった(パワポを触る時間が長かった)
- 直近5年くらいはマネジメントメインでプログラミングをする機会は皆無
- 子供は2人いて9歳と6歳。年齢は今年で40歳
で数学・パソコンオタクがオジさんになって競プロに出会ったという感じです。
- 大学を出て15年近く経ち知識も薄れてしまった
- 難し目の問題も解ける[2]黄Diffまでなら時間をかけると解けることが多いがいかんせん時間がすごくかかる[3]AtCoder Type Checkerだとスコアは13.06で「かなり多く解くタイプ」
- 年のせいか短期記憶が悪くなりケアミスが多い
- 仕事もある(しかも7月に転職した)ので生活に影響が出ないように楽しむ
と昔取った杵柄を取り戻しつつ、年齢によるマイナスを軽減しながら楽しむか?がここ1年のテーマでした。
趣味として競プロ&精進
競プロスキルを伸ばす勉強や練習として
- 書籍やWebからアルゴリズム、手法を学ぶ
- ライブラリを整備する
- PCやコーディング、デバッグ環境を整える
- 実際に問題を考察、実装する&復習する
などがあると思います。
短時間でスキルを伸ばすには弱点の克服やうまく空き時間を使うことも大切だと思いますが趣味なのでその時、その時で気になっていること、面白いと思うことに取り組むのでもいいと思ってて気ままに取り組んでいます。
アルゴリズムの習得、ライブラリ整備
初期のころは知らないアルゴリズムの習得がレーティングに直結しますし、ライブラリの整備も武器を取り揃えていく感じがして楽しいです。
ライブラリ整備は最初、典型的なアルゴリズムを書いてましたが、hamamuさんの色変記事をきっかけに「無駄な思考を減らす」という観点で毎回忘れて調べてしまうこと(lower_boundの仕様など)もライブラリ化するようにしました。
短期記憶の低下は悲しいくらいあって考察で
「Aやって、Bやって、Cやって、あとオーバーフローにも気をつけなきゃ」
と思っても実装するとなぜか「AやってCやって」になりサンプルすら通らず慌てて「AやってBやってCやって」を実装してオーバーフローでWA…が頻繁に起きます。
標準ライブラリにあるような処理も自分の分かりやすいように命名してライブラリ化しておくと思考を問題固有の処理に専念できてケアミス防止につながると思います。
他にも考察段階でどこまで言語化してから実装に移るかの目安も持っておくのも大切だと思います。
自分の場合は解法の大まかなステップと正当性、計算量の評価までは紙でやって実装は考察で書きだしたステップを淡々と書くだけにして、実装中に考察モレに気づいたら紙での考察に戻るようにしています。
環境面
環境は日々接するものなので
- 2画面にすると問題文、コーディング環境の切り替えがなくなり快適
- コーディング環境もフォントや文字サイズを自分にあった設定にする
- お気に入りのマウス、キーボードを見つける
とこだわりを持って整備すると一人悦に入れる[4]家族からは使いにくいと不評だったりしますが…ので色々と試しています。最近、腰や手首に痛みが出るのでオフィスチェアやマウスにもう少しこだわろうかと画策中[5]おススメあれば教えてください。です。
最初のころはVSCodeのデバッガを使ってましたが「競技プログラミングで print デバッグ」を使ってprintデバッグにしています。デバッガでバグが起きる場面をステップ実行で再現しなくて済むのでデバッグ時間が短くなりました。
他にもメモリ周りのバグはやっかいなので手元で実行するときは
$ g++ -fdiagnostics-color=always -g -O0 --std=c++17 -Wall -fsanitize=undefined,address
とsanitizerをonにしています。配列外アクセスやオーバーフローがあるとstack trace付きでエラーになるのでデバッグが効率的[6]特にAHCなどの長期ヒューリスティックコンはこれなしではデバッグできる気がしないです。になります。
あとコンパイル時間の短縮でプリコンパイル済ヘッダを用意しておくことや、性能の良いマシンを買う[7]今年に入ってRyzen 7950X搭載マシンを買ったのですがすこぶる快適です。のも快適な競プロライフにつながると思います。
問題を解く
水色になるくらいまでは
を解いて典型手法を使えるようにしたのが良かったですね。
特に精選100問は問題のリストをシャッフルしてどの手法がテーマなのか分からないようにして最低1時間は考えるようにしていました。時間はかかりました[8]当時働いた会社を辞めることを決めており業務量を減らしに行っていたので少し時間があったが典型的な手法のありがたみを身をもって知ることができてベースづくりに良かったと思います。
今だと鹿本
が内容、量ともに読みやすいですし、網羅的に押さえたいなら鉄則本
で学べると思います。
レート向上の観点では毎週のABCに参加するのと、余裕があるならバーチャル参加が時間の使い方も含めて練習できるので一番良いと思います。特にABCの問題はSnukeさんによる公式解説が素晴らしく
- 自分が解いた問題をより良く解けないか?
- 解けなった問題をどうすれば解けたのか?
を動画見て復習するだけかなり力がつくと思います[9]ABCが終わった後にお酒を飲みながら解説放送を聞くのが至福の時間ですね。。
また、AtCoder Problemsで自分の実力に適した問題やちょっとチャレンジングな問題を簡単に探せるので、自分の課題感に合わせた問題にチャレンジするのもすごく良いと思います。
その際、AtCoder主催のコンテストの多くはテストケースが公開されているので解けない理由が分からないケースがほとんどないのも良いです。
今の会社は幸いなことに残業がほぼないので在宅勤務の日はバーチャル参加をして、出社日は通勤で疲れてしまうので15-20分くらいで解けそうな問題[10]自分のレート-400くらいを目安に選んでいますをサクっと解いて
「AC」の2文字を見てプチ成功体験を味わっています。
年を取ってくると仕事でも趣味でも達成感を感じる機会が減る中で、競プロでレート向上すると達成感を感じられ面白さの一番わかりやすい要素だと思います。
一方でどこかでレート向上も頭打ちになるはずで少し易し目の問題を解いてプチ達成感を味わうのは長く続けるポイントかもと思います。昔、祖母がナンプレを毎日1問解いていたのですがそんな感じで続けるのが将来的な楽しみ方かもなぁと思います。
終わりに
競プロの面白さはもちろんコンテストに出てよい結果を出すことが一番ですが、そこにつなげる活動として
- アルゴリズムを勉強
- ライブラリを整備
- 環境を整備
- 実戦練習
など色々と努力・工夫できるところがあり何かが飽きそうになたら別のことで気分転換できるのも良いところだと思います。
まだ理解の浅いアルゴリズムがいくつもあるのと[11]フローやSuffix arrayなどの文字列系、乱択アルゴリズム、FFTなど、スピード面は経験・知識でカバーできるのでは?と思っているのでもう少し成長余地はあると思っています。
その先は易し目の問題を解いてプチ達成感を味わう日々か、親の趣味につき合わせるわけではないですが、子供がもう少し大きくなった時に興味を持ってくれるといいなぁと思います。その時にあっさり抜かれない程度には実力をキープしたいなと思います。
脚注
↑1 | 無事、表彰制度に組み込めたのですが表彰を前に転職したので私は表彰金をもらい損ねました。 |
---|---|
↑2 | 黄Diffまでなら時間をかけると解けることが多い |
↑3 | AtCoder Type Checkerだとスコアは13.06で「かなり多く解くタイプ」 |
↑4 | 家族からは使いにくいと不評だったりしますが… |
↑5 | おススメあれば教えてください。 |
↑6 | 特にAHCなどの長期ヒューリスティックコンはこれなしではデバッグできる気がしないです。 |
↑7 | 今年に入ってRyzen 7950X搭載マシンを買ったのですがすこぶる快適です。 |
↑8 | 当時働いた会社を辞めることを決めており業務量を減らしに行っていたので少し時間があった |
↑9 | ABCが終わった後にお酒を飲みながら解説放送を聞くのが至福の時間ですね。 |
↑10 | 自分のレート-400くらいを目安に選んでいます |
↑11 | フローやSuffix arrayなどの文字列系、乱択アルゴリズム、FFTなど |
ピンバック: 週記(23/04/02):色変記事 | 有意に無意味な話