AtCoderで水色になったので雑感のまとめ

AtCoderをやっているからには色変記事というものを書きたかったのだが、以前水色に到達したときはすぐに落ちてしまったのでタイミングを逃していた。ようやくまた水色になったので記事にまとめてみる。

レート遷移

こんな感じ。緑にはすぐなれたけど、その後は2年近く停滞していた。

レベル感

職業プログラマーから見た水色までの問題のレベル感。あくまで個人の感想。

灰色

チュートリアル。とりあえず文法を覚えよう。

茶色

初学者なら及第点。仕事でプログラムを書く人には普通に解けてほしい。文字列操作やコレクションの使い分けなど普通にプログラムをバグらせず実装するのに必要になってくる。ただ競技プログラミングでは典型であっても、業務ではあまり使わないものもあるので、初見で解けない問題があってもおかしくはない。

緑色

必要な知識が競技プログラム特有になり、プログラマでもぶっつけでは解けない問題が多いと思われる。Union-FindやSegmentation-Free、ダブリング、座標圧縮、動的計画法など、既存のアルゴリズムを色々と知る必要がある。ただそれらを理解さえすれば解けるので、地道に一通り覚えれば到達できるだろう。

水色

既存のアルゴリズムを組み合わせたり応用が必要になる。もしくは数学要素(漸化式や数列、組み合わせなど高校数学~)の少し複雑な問題が出題される。考察が必要になるため、難易度が高くなる印象。

私は緑にはすぐなれたが水色は時間がかかった。これより上の色は解ける気がしない。

ABCの難易度向上について

近年でABCのレベルが上がっている論がある。下位領域の絶対評価であれば、確かに難しくなっていると言える。特に典型問題のパフォーマンスがガタ落ちしている。これは過去問や解説の充実などにより、典型問題が習得しやすくなったためと思われる。

一方で類題が少なかったり典型から外れた問題は正答率が落ちる。相対評価で言えば参加者のレベルが上がったというよりは、環境が整ったと言う方が正確だろう。

なお仕様変更でUnrated戦略(問題が解けた場合だけ参加する)が使えなくなったため、変に低いレートが出ることは減った。

学習法など

シンプルに過去問題を解きながら分からなければ解説を読むのが基本。場合によっては別途アルゴリズムの解説を探す。典型のアルゴリズムなどは、その中身を理解しているかどうかで応用力が変わるので、できればアルゴリズムの中まで踏み込む。

またコピペ用ライブラリは積極的に作成した。C#なのでACLは使っていない。基本的には自前で実装したコードを保存している。特にセグメント木などは場合によって演算内容が異なるので、自力で改造できる状態が良い。

しゃくとり法と二分探索は理屈は簡単だが実装はバグらせやすく、コピペ化しにくい。自分なりの実装手順を確立しておくといい。

簡単な問題の穴埋めの是非

コーディング作業に慣れていないのならあり、そうでないならほぼ無意味。できる問題をいくら解いても、できない問題ができるようにはならない。初学者でプログラム経験の絶対量が少ない場合は、コーディングの訓練にはなる。(とはいえそれならもっと意味のあるコードを書いたほうがいいとは思うが)

ただ問題は解けると嬉しいので暇つぶしに穴埋めしたりはした。

解説ACと写経の是非

解説ACは可能な限り日本語の説明で理解したほうが良い。ソースコードはただの記述フォーマットでしかないので、本質はコーディング以前の部分にある。写経は個人的には無意味だと思う。人のソースコードを見たり真似するのは良いことだが、手作業でのコピペはアルゴリズム力向上にはあまり意味がない。

コンテストのテクニック

普通にAから解いてるので大したことはないが。

テスト環境を作る

業務でもテストはある意味コーディングよりも重要なので、職業プログラマを視野に入れてる学生などはテスト環境を作ってみて欲しい。テスト環境がまともであれば最悪のケースは防げる。

私はVisualStudio Communityを利用しているが、デバッグ時はテキストファイルからテストケースを取得し、実行時間も計測するようにプロジェクトを構築している。また10^5などのテストケースを作成するクラスなども用意している。

紙に書く

問題を解くときに紙に書いて整理する。地味に効果が高い。数列やグラフなどはビジュアル化することで気づくことは多い。方程式なども紙に書いたほうが早い。前時代的にも聞こえるがおすすめだ。

業務プログラムに役立つかどうか

業務プログラムといっても様々なので場合によるとしか言えないが、アルゴリズム力という点では、現実的には直接使う機会は少ないだろう。検索アルゴリズムなどは下手に自作するよりも用意されたものを利用した方が確実だからだ。ただ役に立つ面もある。

アルゴリズムの利用者として

用意された部品の内部アルゴリズムを大まかに理解していれば、実行効率を予測することができるようになる。LinkedListとArrayListなどデータ構造の違いは大きい。

コーディングの訓練として

初学者は思っている以上にコーディングの絶対量が足りていない場合がある。基礎練ではないが、何度も繰り返すことで頭の中をソースコードに置き換える作業がスムーズになっていく。ただし、コンテストの提出コードは使い捨て前提で保守性や安全性を無視している場合が多いので、その辺の癖には注意が必要。

茶色問題を確実に

業務プログラムに役立てるなら、まず茶色レベルの問題、ABCのC問題までを確実に解けることを目標にするといい。それ以上は無駄ではないが趣味の領域に入る。

今後について

これ以上は勉強にも時間もかかりそうだし、現状あまりレート上げに実益がないので、ぼちぼち趣味程度に続けようかなという感じ。本腰を入れるにはもう少し権威付けが欲しいところ。

コメント