valid,invalid

関心を持てる事柄について

データ構造とアルゴリズムの基礎を100時間学習してみての所感

4月中は3週間ほど仕事をせず引きこもる時間があったので「データ構造とアルゴリズム」の基礎の学習に100時間ほど費やした。

f:id:ohbarye:20200511013957p:plain
あくまで目安としてSpreadsheetで学習時間を記録した。厳密ではない

学習においては量(時間)だけでなく質のほうが大事で、費やした時間で語るのはアンチパターンだと考えているが、「100時間でどれぐらい進捗するのか」のベンチマークとしてはわかりやすいと思うので参考までに書いておく。*1

インプット

データ構造とアルゴリズムをきちんと体系立てられた書籍やオンライン講義動画で学んだ。

あとは細かい記事を色々読んだり。

Coureraの "Algorithms Part I" に57時間、『みんなのデータ構造』に14時間ぐらい使っているので総合したら70時間強はインプットに費やしたことになる。

時間のほとんどはインプットに振ったにも関わらず全然足りない…と感じている。Courseraのアルゴリズムの基礎講座も半分だけだし、AtCoder水色になるために必要な知識群には半分も着手できていないし、データ構造とアルゴリズムに関連する数学の学習はほぼゼロに近い。無職を超えてさらなる無限の学習時間がほしい

アウトプット

「インプットした事柄の定着」と「理解度の測定」を目的とし、主に競技プログラミング、AIZU ONLINE JUDGE、LeetCodeを活用した。正確じゃないけど30時間ぐらいはやっていたはず。

期間中に計150問ぐらい解いて確かに目的に合致することも多くあったが、演習量も質もまだまだ不足を感じる。最近は"解ける問題を選んで解いている"感があって、なお良くない。

f:id:ohbarye:20200522004020p:plain
問いた問題数など (期間外も含む)

予想通りではあるが上述のインプット(初歩的なデータ構造と初歩的なアルゴリズムの学習)だけで劇的に競技プログラミングの成績が向上するわけではなかった。題意をつかむことや問題の考察、適切なアルゴリズムを当てはめて問題を解くにはそのための訓練が必要。それでもじわじわ伸びているとは感じており、AtCoderではようやく緑に昇格し、A~D問題は安定して解けるようになってきた。

所感

100時間やってこの程度か…という気持ちが強い。今の感覚だと400時間ぐらい、質を高めても250時間ぐらいは学習しないと一山を超えられない気がする*2

とはいえ、基礎(の一部)を学ぶことで問題の解説を読んで理解ができるようになったり、新しいアルゴリズムを学ぶときに必要となる土台を獲得出来てきたと感じる*3。 初歩的な知識があれば考察を必要としないような典型問題*4はわりとすらすら解けるようになってきた。前回のABC 168 D問題でBFSをさらっと書けたときは嬉しかった。

また、学んだデータ構造やアルゴリズムは本当に基礎的でありながら実用的であることがわかってきた。 ライブラリや言語やミドルウェアの内部実装を読むのにたまに便利で、時折、暇を見つけて以下のようなトピックを色々見ている。

今後

30代はこれまで避けてきた領域と本格的に向き合いたい*5と考えており、余暇でデータ構造とアルゴリズムの学習は継続するつもりだ。

基礎分野を学習するほどに「これまでよく知らずにやってこれたな…」と凹むことも多いが知らないのだから知るしかない。

とはいえ自分は個人的な学習において1つのことを数ヶ月単位で続けられない飽き性なので、5月は別の領域を学び、数週間後に戻ってくることにした。

次に再開するときにはCoursera, Algorithms Part 2でより基礎を深めつつ、実戦で使える引き出しをもう少し増やすための本も併読したい。

200時間学習した時との差分比較が楽しみだが、その頃には学習時間の計測に飽きていそうな気もする。

*1:せっかく記録したのだし…という気持ちもちょっとあるし量が質に転化するのを信じたい気持ちもある

*2:なんの定量性もないただの勘

*3:クラスカル法を学ぶ土台としてのUnion-Findとか、グラフを扱うアルゴリズムを学ぶ土台としてのDFS, BFSとか

*4:特にLeetCodeのEasy全般とMediumの一部でLinkedList, Stack, Heap, Priority Queue, HashMap, BFS, DFS, Tree, BT, BST, Sort, Binary searchあたりを扱うやつ

*5:大学では人文系を専攻し、プログラマとしてのキャリアでは長らく場当たり的に学習を続けてきたツケを払うターン