31歳の元保守運用エンジニアがAtCoder初参加してみた



最近競技プログラミングについて知ったので、挑戦してみた。
以下その体験談。
## スペック
・31歳の製造業勤め
・情報系の学部+院卒
・かつて情報システム課勤務だったが、メンタルを病んで複数回休職する
　現在は別の課所属。
・実勤務期間は4年くらい?
・扱える言語はJava中心、サブでJavaScript
・大学+大学院時代も含めてJavaを10年扱ってきた
・業務は社内システムの保守・運用のみのため、開発経験はなし
・アルゴリズムなんもわからん
・個人開発に興味あり

という程度。
## きっかけ
最近また復職し、時間に余裕があることで何か自己啓発したいと考えるように。
Qiitaで記事を探してみたら、偶然競技プログラミングの記事を見つけた。

https://qiita.com/drken/items/fd4e5e3630d0f5859067

https://qiita.com/e869120/items/f1c6f98364d1443148b3

目的があるとやる気も出てくるなと思い、実践してみた。
とりあえず緑色を目標に。
競技参加する前に、初心者向け記事や過去問を解いてみる。
使う言語はやはりJava。
やってみると、まあ解けない。A問が解けてやっとというレベル。
B問に至っては問題文を理解する段階でつまずくものもあった。

散々だけれども、試験の参加と過去問を繰り返すのが大事と思い、2023/12/2開催のABC331で初参加してみた。

https://atcoder.jp/contests/abc331

## 初参加してみる
時間になって、まずA問から解き始める。問題も理解し、コードに反映させることができたので、正解しただろうと判断。
しかし結果は**WA(不正解)**。
ここでいきなりつまずき、頭に血が上り始める。

**「これはAtCoderの陰謀だ」**
**「コンパイラがウソをついている」**
とそれはそれは醜い言い訳をモニタの前で言いまくった ~~(本当に言いました)。~~ 
しかも問題を解き始めて30分ほどここで足踏み。
結果、自分の頭ではダメだと判断しChatGPTに自分のコードを改善してもらった。

旧コード↓
~~~A-Tomorrow.java
		int allmonths = Integer.parseInt(inputed1[0]);
        int alldays = Integer.parseInt(inputed1[1]);
        int year = Integer.parseInt(inputed2[0]);
        int month = Integer.parseInt(inputed2[1]);
        int day = Integer.parseInt(inputed2[2]);
        
        int answerYear = year;
        int answerMonth = month;
        int answerDay = day;
        
        if(day == alldays) {
        	answerDay = 1;
        	
        	if(month == allmonths) {
        		answerMonth = 1;
        		answerYear++;
        		
        	} else {
        		answerMonth = month++;
        		
        	}
        	
        } else {
        	answerDay++;
        	
        }
~~~

新コード↓
~~~A-Tomorrow.java
        int answerYear = year;
        int answerMonth = month;
        int answerDay = day + 1; // 次の日に設定

        if (answerDay > allDays) { // 次の日が次の月になる場合
            answerDay = 1;
            answerMonth++;
            
            if (answerMonth > allMonths) { // 次の月が次の年になる場合
                answerMonth = 1;
                answerYear++;
            }
        }
~~~

肝心なのは旧コードの以下から始まるネストの部分。
~~~
if(day == alldays) {
        	answerDay = 1;
         ……
         } else {
        		answerMonth = month++;
~~~
このネストの中で、日付が翌月の1日になる場合の、月度を切り替える処理に問題があった。
変数**answerMonth**にmonthをインクリメントして代入しているが、この記述だとanswerMonthにはインクリメントされる前の値が代入されてしまう。そのため意図した値にならない。
初歩的なミスだった。
ただそれだけだったが、回答中は気づけず煩悶することに。
ChatGPTによりスマートな分岐に書き換えてもらい、問題の処理も改善され、提出したところAC(正答)に。

結局、最初の問題でこれだけ疲弊してしまい、時間もB問を解く気もなくなり、今回はここでギブアップ。
もっと基礎を固めようと思った。

## 振り返り
過去問を解いていた段階で気づいていたが、やっぱり結果はA問1問のみ完答。B問は着手すらできず。
ただ、「もう競技プログラミングなんて、決してやらないようにするよ」
とはならなかった。
言い訳ではあるけど、開発なんて入社以来全然してこなかったし、保守くらいでしかコーディングしなかった。
自分のレベルの低さは実感できたし、これから伸ばせばいいかと反省。
これからも過去問を解いて、ABC参加を定期的にやっていこうと思った。

## 変更点
ただ、使う言語はJavaから**C++** に変更。
理由としては
・公式解説で使われている
・処理速度が高い
ため。
図書館で「C++の絵本」を借りて軽く学習した。
これで過去問を解くうちに慣れたので、次回からはC++で挑む。

https://www.amazon.co.jp/C-%E3%81%AE%E7%B5%B5%E6%9C%AC-%E6%A0%AA-%E3%82%A2%E3%83%B3%E3%82%AF/dp/4798108936/ref=sr_1_2?adgrpid=89520218304&gclid=Cj0KCQiAm4WsBhCiARIsAEJIEzVzDiw1kIYdJ-c8bdeRK8bUUX4A6YPom6Y1HXPWVFyrvVvS98PVHOAaAj1oEALw_wcB&hvadid=651071638720&hvdev=c&hvlocphy=9053369&hvnetw=g&hvqmt=e&hvrand=1204990673420298210&hvtargid=kwd-853090039381&hydadcr=4771_13316645&jp-ad-ap=0&keywords=c%2B%2B%E3%81%AE%E7%B5%B5%E6%9C%AC&qid=1702993008&sr=8-2


ただ、もしかするとpythonを学んだほうが良かったかも。
公式解説+ユーザ解説にほとんどpythonでの解答例が掲載されているし、ネットで参加者の回答ブログを漁ってみると大体がpythonだった。
機会があればまた乗り換えるかも。

## 方針
文中でさらっと使っていたけれど、**ChatGPTは使っていきます。**
ただ、丸々問題を解かせるのでなく、あくまで今回のように
・自分なりに解き、正答と自信のある回答を作る
・それでもうまくいかないとき、ChatGPTに頼る
という形で使っていく。
というのも、今回詰まった点のように、初歩的なミスで時間を空費するのは不要なストレスかな、と判断したため。
問題そのものが解けなかった場合、その問題は捨てて別の問題に取り組むようにする。
自分で解く能力は鍛えたいけれど、ケアレスミスで発生するストレスと天秤にかけた結果として。