文系出身者がAtCoderの過去問400問解いて得た成長と学び

初めまして！CREとしてエンジニアをやってますkazuです🦌

AtCoderの問題を2023年12月から解き始めて、2024年10月で400問を達成したので、そこで得たこと・気づいたこと・考えたことを共有しようと思います！

![スクリーンショット 2024-10-06 20.28.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2597943/32cc27a9-787f-2203-943b-ef2b8ffffc93.png)


やり始めた経緯などについては、以前の記事があるので、気になる方はご覧ください✨

AtCoderの過去問100問解いて得たこと

https://qiita.com/kazushika/items/07ac25930d859ed15e91


こちらは前回の記事

https://qiita.com/kazushika/items/27118d1508450ad185b9

# B問題200問解くことでできるようになったこと

- 読解力の向上→細分化の粒度が細かくなった
- アルゴリズムとデータ構造の理解度向上
- 問題解決へのアプローチの多様化（処理のレパートリーが増えた）

## 読解力の向上→細分化の粒度が細かくなった

B問題をひたすら読み続けることで、問題文を読みながら「この関数を使えば解決できそう」といったある程度の予測が立てられること自体、問題文をしっかり理解している証拠だと僕は思っています。逆に、どの関数を使えばいいのか、どのような処理にすれば良いのかが全く思い浮かばない時は、問題を十分に理解できていないことが多いです。

B問題を数多くこなすことで、全く思い浮かばないことは減りましたが、それでも理解が不十分なときはアウトプットの粒度が荒いです。

AtCoderにおける読解力とは、問題に対する深い理解だと思っています。出題される問題に出題される語彙の一つ一つ、文章間の結びつきから文脈を読み取る能力など、細かい部分への理解が読解力向上に繋がったと思います（とはいえ、まだまだ改善の余地はありますが…💦）

読解力が向上したことで、整理すべき情報を適切に洗い出し、それを細かい粒度で処理に落とし込むことができるようになったのは進歩だといえます。

## アルゴリズムとデータ構造の理解度向上

B問題では基本的なアルゴリズム（線形探索、ソート、累積和など）を多く使うため、それらを何度も実装することで自然と身についていきました。自分と他人のコードを比べたり、「より簡潔に処理を書くにはどうすべきか？」と考えたり、自分以外の人の視点を取り入れることで、処理が美しくなっていく過程はとても気持ちいいです。

## 問題解決へのアプローチの多様化（処理のレパートリーが増えた）

B問題を多く解くことで、数値処理、文字列処理、関数の組み合わせ、ソート、探索など様々なパターンに触れる事で、問題解決に向けたアプローチの方法が増えたように感じます。また多く解く事で「この問題は以前解いたこの方法が使えるかも！」といった感じで自分の記憶から適切なアルゴリズムの実装を選択できるのも数をこなすメリットかもしれません。こうした多様なアプローチ手段を持つことは、初見の問題に柔軟に対応できる力を身につけることだと思うので、引き続き解いていこうと思います。

# 100→200問を解く中で、工夫したこと

- 状態・条件・処理で考える
- 抽象化する意識

## 状態・条件・処理で考える

よくよく考えると、どの問題も状態・条件・処理によって解決策を出すことができるなと考えました。「データが今どんな状態か」「それに対する条件は何か」「それらをどう処理していくのか」など処理に対するフローを細分化した感じです。

実はこの考え方は、実務において社内システム自動化プロジェクトの設計を任せられた経験があったから、思いついた方法でした。設計を行うにあたり各フローごとに、上記のような考えをもとに進めていくために、それを処理単位まで落としこみました。

![スクリーンショット 2024-10-06 18.16.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2597943/764272cc-c529-7d36-4722-f31f3a4ae766.png)


## 抽象化する意識

AtCoderの問題で、抽象化することにあまり意味はないのですが、実務を意識した結果抽象化することを始めた感じです。関数ごとに役割をまとめる意識をする、これはただ関数をAとBに分けるというより、「なぜAとBにわけるのか？」「どこまでの範囲をAとし、どこまでをBとするか」など今後保守しやすいか、再利用しやすいか、可読性があるかを常に意識したコードを心がけようと思った次第です。（まあ、毎回やっているわけではないので、気まぐれになるのですが..笑）

ただ、やはり、関数が2つくらい必要になったときは、ぐちゃぐちゃ一気に書くより、役割を分けた方が見やすいコードになっているなと実感もあります。

# 得られた成果

- 問題文を理解する力
- 理解を促進するための効率的なChatGPTの使い方
- 自分の得意なパターンと苦手なパターンの明確化

## 問題文を理解する力

100問から200問にかけて、工夫した事で紹介しましたが、状態・条件・処理という形で起こし込む前提で問題文を読むので、前よりも読解力は向上していると思います。目的意識があって読むのと漠然とただ読むのでは、その後のコードの質が全く異なることを痛感しました。

## 理解を促進するための効率的なChatGPTの使い方

基本的に、ChatGPTの利用シーンとしては以下になります。

- 自力で解けない問題を解いてもらう/状態・条件・処理の洗い出し/コードの解説
- 他人のコードで理解ができないコードの解説

こんな感じで使用しています。ちなみに、15分経って何も進捗がない場合は、すぐChatGPTに聞きます。（まれに、問題文を読んでも？？？となることがあるので笑）

答えを知ることが目的ではないので、正解となる処理を見た上で改めて問題文を理解して、腹落ちさせるといった感じで使用しています。

あとは、他人のコードで自分があまり書かないようなパターンで処理を書いているときは、リーディングが曖昧な時があるのでそういうので解説をしてもらったりしてます。

過去問を解いているだけなので、じっくり考えるというよりは、理解の幅を広げることを目的にどんどん進めている感じです。

ChatGPTは、自分が知らないこと、分からないことをなんでも教えてくれる便利ツールですが、使い方を間違えると諸刃の剣にもなるので、思考を任せる部分、任せちゃいけない部分は常に意識しながら使っています。

## 自分の得意なパターンと苦手なパターンの明確化

200問解いていると、「自分が得意なパターン」「苦手なパターン」「自分が普段使いする関数」「扱いやすいデータ型」など自分の癖のようなものがはっきりしてきます。プログラマーとしての輪郭とでもいうべきでしょうか。

なので、他の方の処理を参考に、普段自分が描かない書き方を真似してみたり、あえて配列を使用してみたり、敢えてめんどくさい書き方をしてみたりとにかく手を動かして、色んな方法を試すことを心がけています。

# 500問に向けて、次回以降取り組みたいこと

- 復習する時間を取る！！！

## 復習する時間を取る！！！

前回の記事でも、復習する時間を取ることを明言していたのですが、中々その時間を取ることができず、できませんでした。なので、自分の苦手な問題を中心に、再度取り組んで理解の幅を広げたいと思います。

# まとめ

この取り組みを始めて1年以上が経過しましたが、なんだかんだ学びが多いな思います。何事も継続して、取り組んでいると自分の力の糧になるなとひしひしと感じています。500問まで残り100問ときましたが、この調子でとりあえず1000問までは続けてみたい思います。