ごまだれ日記

プログラミングの技術メモとか

2023年の振り返り

印象的だったトピックごとに、ざっくりと2023年を振り返っておこうと思う。

競プロ

去年に引き続き、個人的に最も関心が高いトピックは競プロだった。2023年はAtCoderのコンテストには34回Rated参加し、5回Unratedで参加していた。レートは2022年末と比べて+153で、1年間での進捗としてはパッとしない。色も茶色のまま変わらず。まあそれでも去年は1度も出なかった緑パフォが何度か出たのでいくらかは成長していそう。時間が限られる中での取り組みなので、まあこんなもんかなという感じ。ペースを上げるよりかは、マイペースで継続していく方針でいきたい。

レートの変動は大きくないが、それでもなんだかんだで色々なことがあった。緑パフォをとったこともあったが、逆に1完爆死したり、激遅2完灰パフォ爆死したり、などもあった。それらの回では2次元のグリッドを探索する問題が解けずにそのようなことになった。解法は明らかで、アルゴリズムとしてはただの全探索なので、ただその通り実装するだけでよかった。なのに実装しきれなかった。自分はグリッド系の問題が苦手なのだと思った。
しかし、それは正確な認識ではないと後から思った。グリッド系というか、単純にプログラミングが苦手なんじゃないかと…
プログラミングって実は「ちゃんと」できなくてもなんとなくそれっぽいことをして、動作確認をして、違ったら対症療法的な修正をして、というノリで案外できてしまう。偶発的なプログラミングというか。自分はそのレベルだったのだと気づかされてショックを受けた。しかしそれが現実なので、克服するために実装が面倒な問題を募集して解いて練習するなどの取り組みを行なった。
そういう実装が重い問題を続けて解いていくことで、それなりに改善することができたと思う。なんというか、真面目にコードと向き合えるようになったというか。提出しても通らないなら、コードが間違っているということ。それに対して修正ガチャみたいなことをするんじゃなくて、本来あるべき姿を真面目に考えてそれとの差分を探すべき。というか、最初からあるべき姿通りに実装するべき。まだ満足できる水準じゃないけど、以前よりはできるようになったと思う。
お恥ずかしい話だが、提出してWAが出た場合、なんでだよーーとちょっとキレそうになることがよくあった。なんでって、お前が書いたコードが間違っているからだが…?という。WAが出た時に、修正するにあたって頼れるのは結局自分。頼れる自分になりたい。なろう。

こういう偶発的なプログラミングのような悪い癖を矯正するための手段として、競プロはすごく良いと思った。競プロの良いところは、優秀な人によって作られたテストケースによって容赦なくテストされること。偶発的プログラミングなんてしていていたら容赦なくWAになる。何度もその洗礼を受けた。これは、プログラミング言語の入門書に沿って写経したり、おもちゃのようなプログラムを書いたり、という勉強では得られない。
もちろんおもちゃではなく実使用に耐えるようなものを作ってリリースして多くの人に使ってもらう、という取り組みをすればさらに容赦のないフィードバックを得ることができると思うが、そこまでやるのはなかなか大変。それに比べて競プロは手軽に始めることができる。

なんというか、コードをちゃんと手懐けることができていないと、偶発的プログラミングにつながりやすいと思った。考察が不十分なまま実装が先行したり、読みやすさを考えずにただただコードを書き下したりすると、コードはあっという間に手に負えないモンスターと化す。自分で書いたコードなのに、読んでもよくわからない。修正するのが辛い。関数に切り出すなどをせずにコピペとかしたらもう最悪である。それでも通るならまだ良い。でも通らなかったら?モンスターコードを修正しなければならないとしたら…?たぶん、出力に合うように細部に対症療法的な修正を施してお祈り提出とかするだろう。そして祈りは天に届かない。
さすがに、業務でそこまでひどいプログラミングをしたことはない。しかし、競プロではやってもいいと思っていた。スピードが重要なので、いくらか雑になってもいいと思っていた。大間違いだったわけだが。そこで、競プロでもちゃんと方針が立つまでは実装に着手しないようにして、時間をかけない程度に可読性も気にかけて、できるだけ関数化して、などを考えるとだいぶ良くなった。それでちゃんと問題が解けると嬉しいし少し自信がつく。何より、久々にプログラミングって楽しいなと思えるようになった。初心に帰れたというか。

まあ、それはそれで良いことなのだが、レートを上げていくためにはそれだけでは不十分。レートを上げるには現状解けない問題も解けるようにすることが必要だが、2023年はそのための精進の方針はけっこうブレがちだった。
今考えていることとしては、とにかく典型を身につけることが重要じゃないかということ。ABCの問題は全部典型らしいし、自分が今まで良いパフォが出た回はいずれも自分が既に身につけている典型パーツに当てはめて解くことに成功した回だった。それを全ての回で再現できればレートは上がるはずだろうと。 しかし、典型を身につけるというのは決して簡単ではない。身につけるべき典型パーツの数が単純に多いというのもあるが、何より解説記事などを読んだところで身につくとは全然限らないという問題が大きい。私の場合、問題の公式解説を読んでもわからず、解説動画を視聴してもわからず、有志の解説記事を読んでもわからず、ということが非常に多いのである。わからないというのは、おそらく解説を理解するための前提知識が足りないか、必要な頭の使い方が身についていないかのどちらか、あるいは両方だと思う。落ち着いて何がわからないのか分析して、わからない部分を遅延評価で調べて、を繰り返していけばいつかは理解できるかもしれないが、その間にも脳は悲鳴をあげっぱなしなので辛すぎて途中でやめてしまうことがほとんどである。
知識なら調べればいいんだけど、ネックなのは知識というより頭の使い方だと思う。数式などを読むとき、一旦脳内メモリに保存して先を読んで、とかしているうちに脳内メモリに置いたはずの情報が蒸発していてパニックに陥る、みたいなことが頻発する。数式を読み慣れている人なら息を吸うようにできる頭の使い方が私にはできないという感じがする。 これはどうしたらいいんだろうな。途中でやめるなよといえばそうなんだけど、いやほんと脳が悲鳴をあげて辛いんですが。でもやるしかないのかなあ。2024年はもうちょっと頑張ってみるか…
脳内メモリだと蒸発するなら紙にでも書いておくとか、その気になればやりようはあるかもしれない。

数学

競プロの問題の解説が理解できないのは、間違いなく数学ができないことに起因していると思う。そのため、競プロとはまた別枠として数学の勉強もしていた。小学校レベルからやり直して、とりあえず中学レベルまでは勉強しなおした。また、競プロは離散数学の実践編であるという意見を見たことがあって、それならばと離散数学の本も読んだりした。まだまだ効果を実感できるところまで来ていないので、今後も取り組みを続ける必要がありそう。まあ、どうやって取り組むのがいいのか悩ましいんだけども。

競プロというか、プログラミング自体が離散数学なんじゃないかと思った。

論理も集合も離散数学の分野である。それも、特に中核を成すような分野であることは私でも想像できる。
プログラムには入力と出力があり、入力としてあり得る値も出力としてあり得る値も集合として考えることができる。それらの集合をマッピングするのがプログラムだし、どのような規則でマッピングするのか決めるのが論理、とするとプログラミングとはまさに集合と論理の実践編なのだと言えそう。

そう考えるとプログラミングをやる上で数学が重要ではないはずがない。プログラミングはやったことなかったけど数学が得意な学生が、けっこう短期間でAtCoderで緑や水色に到達するのも納得がいく。知識というより、数学とプログラミングで頭の使い方がほぼ同じなんじゃないかと思う。
たしかに数学が苦手なままプログラミングを始めることはできるし、そのままプログラミングが得意だと言える水準に到達する人もいるんだけど、それってプログラミングから逆算して論理と集合を身につけることもできるってだけなんじゃないかと…
(上で書いたように偶発的プログラミングをしているだけかもしれないし、あとは実用的な高レイヤーのプログラミングはただ部品を組み合わせるだけでできるという面もあるし、とかを考えると、自分はプログラミングができると思っている人でも実はできていないってこともあり得るが)

それと関連して、プログラムの正しさはかなりの部分を論理と集合で担保できるのではないか、という気もしている。

プログラムの期待動作は人間が決めることではあるんだけど、論理的に破綻しているプログラムの動作が期待通りであることはおそらくないので、少なくともそのフィルタとしては役に立つんじゃないかと。であれば、数学ができる人がプログラミングすると、そもそもバグを作り込みにくいんじゃないかと想像している。

それの実践編という感じで、形式手法とかプロパティベーステストといった手法が存在しているらしい。2024年はこれらに関する勉強もしたいと考えている。

自己研鑽

自己研鑽はほぼ数学と競プロに全振りとなってしまった。それも悪くないんだけど、他にもやりたいことはあるので、一旦精進を止めて他のことをやる時期も設けたい。(並行は無理…)

健康

2023年は体調不良に見舞われた年でもあった。3月か4月くらいから、なんだかんだ半年近く苦しんだ。とにかく疲労感が強くて、仕事はなんとか頑張るとしても、終業後はぐったりして何もできなくなった。その間は競プロの精進もほぼ止まったし、コンテストもあまり参加できなかった。原因はよくわからなかったけど、どう考えても健康的な生活習慣ではないことによる影響がまず疑われたので、生活習慣を大きく見直すこととした。

ざっくり以下のような感じ。

  • 運動する
    • 一日一万歩を目安に歩く
    • 筋トレをする(とりあえず自重で)
  • 健康そうなものを毎日食べる
    • サラダ(主にレタス)
    • みかん
    • バナナ
    • ヨーグルト
    • 毎日ではないがりんごを丸かじりすることがある
  • タンパク質を一日に最低60gは摂る(できればもっと)
    • プロテインも飲むが、それだけでは足りないので食べる物はタンパク質の含有量をガン見して決める
  • 食事制限
    • 摂取カロリーは一日1900kcal~2000kcalくらいにする
    • リーンゲインズ(16時間絶食)
  • サプリ類を飲む
  • 腰痛改善
    • 整体に行く
    • スタンディングデスクでできるだけ立って仕事する

あれこれ同時に試したので何が功を奏したのか不明だが、驚くほど症状が改善した。体感としては、ここ何年かで一番体調がいい。怪我の功名!
食事は主にコンビニに頼ることになった。コンビニ食に健康的なイメージはないかもしれないが、栄養成分をちゃんと見て選べば意外といい感じになる。(弁当はダメな事が多いが)
残念ながら食費は高くなった。サラダだけでも400円以上するし… まあそれで健康を保てるならいいか。自分で作ればもっと安くできるかもしれないがめんどくさい。金で解決するならそれでいいや。

ただ、毎日そのような食事だと、食事がただの作業となって楽しみがない。なので週一くらいはあまり気にせず好きに食事している。最近はよくラーメン屋に行く。

ラーメンの良さに気づいたのはけっこう最近。単純においしいってのもあるが、ラーメン屋を巡るという行為が楽しいとも感じた。ラーメン屋はたくさんあるし、バリエーション豊か。普段のウォーキングコースにもまだ未訪問のラーメン屋が多くある。一通り行ってみたいところ。

仕事

仕事柄、あまり内容を明らかにできないのでぼんやりしたことだけ書く。現職および今着任しているプロジェクトにはそれなりに長く関わっているが、学べることが非常に多くて感謝しながら働いている。かなりコアな部分の設計から関わらせてもらったが、2023年にそれが本番リリースされた。恐れていたほど大きなトラブルは発生しておらず、すごくホッとすると同時に自信にも繋がった。
とはいえ、まだまだこれから。引き続き同じプロジェクトに関わっていく想定で、運用期間が長くなると何かと問題も発生するかもしれないが、自分がかなり初期から関わったシステムで問題が起こったとしたら、それは自分の設計や実装に対する重要で貴重なフィードバックとなる。それが今後得られるとしたら、こんなにありがたいことはない。関係各位には感謝しかない。
2023年は収入も増えたし、2024年には新たなチャレンジができそうなお話もいただいている。苦労することも増えるかもしれないけど、全て成長のための糧としていきたい。

なお、現状の自分は主にバックエンドを担当するシステムエンジニアに相当する。このレイヤーだと、大量のデータを高速に処理するような処理を自分で書くことはほぼなく、そういうのはDBに任せる形になる。バックエンドと言っても本当のバックエンドではなく、本当のバックエンドの処理を呼び出すためのインタフェース周りを設計、実装する役割という感じ。自分が競プロは強くないのにITエンジニアとして働けている理由はそこにある。レイヤーが違うというか。本当のバックエンドを担当する人は、コンピュータサイエンスを修めたガチの専門家なので年収の桁が違う感じだと思う。
そういう意味での自分の立ち位置がなんとなくわかったのも競プロのおかげかもしれない。今の仕事も十分に良いのだけど、もうちょっとでも近づきたい気持ちはあるよねぇ。

ゲーム

今年はやはりティアキンの年だった。半年くらい、時間にすると400時間近くプレイしていた。詳細は別途記事を書くかもしれない。

今はグノーシアをプレイしている。2024年はこういうインディーゲームも開拓するつもり。