最近競技プログラミングについて知ったので、挑戦してみた。
以下その体験談。
スペック
・31歳の製造業勤め
・情報系の学部+院卒
・かつて情報システム課勤務だったが、メンタルを病んで複数回休職する
現在は別の課所属。
・実勤務期間は4年くらい?
・扱える言語はJava中心、サブでJavaScript
・大学+大学院時代も含めてJavaを10年扱ってきた
・業務は社内システムの保守・運用のみのため、開発経験はなし
・アルゴリズムなんもわからん
・個人開発に興味あり
という程度。
きっかけ
最近また復職し、時間に余裕があることで何か自己啓発したいと考えるように。
Qiitaで記事を探してみたら、偶然競技プログラミングの記事を見つけた。
目的があるとやる気も出てくるなと思い、実践してみた。
とりあえず緑色を目標に。
競技参加する前に、初心者向け記事や過去問を解いてみる。
使う言語はやはりJava。
やってみると、まあ解けない。A問が解けてやっとというレベル。
B問に至っては問題文を理解する段階でつまずくものもあった。
散々だけれども、試験の参加と過去問を繰り返すのが大事と思い、2023/12/2開催のABC331で初参加してみた。
初参加してみる
時間になって、まずA問から解き始める。問題も理解し、コードに反映させることができたので、正解しただろうと判断。
しかし結果はWA(不正解)。
ここでいきなりつまずき、頭に血が上り始める。
「これはAtCoderの陰謀だ」
「コンパイラがウソをついている」
とそれはそれは醜い言い訳をモニタの前で言いまくった (本当に言いました)。
しかも問題を解き始めて30分ほどここで足踏み。
結果、自分の頭ではダメだと判断しChatGPTに自分のコードを改善してもらった。
旧コード↓
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++;
}
新コード↓
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++で挑む。
ただ、もしかするとpythonを学んだほうが良かったかも。
公式解説+ユーザ解説にほとんどpythonでの解答例が掲載されているし、ネットで参加者の回答ブログを漁ってみると大体がpythonだった。
機会があればまた乗り換えるかも。
方針
文中でさらっと使っていたけれど、ChatGPTは使っていきます。
ただ、丸々問題を解かせるのでなく、あくまで今回のように
・自分なりに解き、正答と自信のある回答を作る
・それでもうまくいかないとき、ChatGPTに頼る
という形で使っていく。
というのも、今回詰まった点のように、初歩的なミスで時間を空費するのは不要なストレスかな、と判断したため。
問題そのものが解けなかった場合、その問題は捨てて別の問題に取り組むようにする。
自分で解く能力は鍛えたいけれど、ケアレスミスで発生するストレスと天秤にかけた結果として。