TRISHAFT

TypeScript で AtCoder をやって思ったこと

  #プログラミング#TypeScript

ここ最近、アルゴリズム力の強化の必要性を感じて、 AtCoder の過去問を TypeScript で解いていた。

TypeScript で問題を解いた数ランキングでそれなりの順位まで来たため一段落、ということで色々とまとめておく。

解く環境や解いたコードはリポジトリに上げているので、それを見てもらうのが良いかも。そもそもの標準入力の取り方とか、いきなりやろうとするとちょっと苦労するし。

TypeScriptのAC数ランキング
TypeScriptのAC数ランキング

あと、自分用のメモとして簡単なチートシートも作ってみたので、良ければ参考に。

なぜ TypeScript?

TypeScript にもっと慣れるため、というのが第一。

現状、Webフロントエンドで何かを作るのであれば TypeScript 以外を使う動機はほとんどない。個人的には WASM にかなり期待しているけど、今の時点では明らかに時期尚早。

ということで TypeScript 一択なんだけど、こいつがなかなか癖が強い。元々の JavaScript に由来する部分だったり漸進的型付けだったり。普通に使う分にはあまり理解していなくてもそれほど困るわけではないけど、アルゴリズム力を鍛えるついでに知見を深めておこう、ということで。

あと、競プロで使う言語としては主流ではないので逆に使ってみたい、というひねくれた理由もある。

TypeScript は競プロに向いているか?

個人的な意見ではあるけど、総合的に見るとあまり向いていないと思う。ガチるのは明らかに厳しい。軽く解くレベルならそれなりにイケるけど、それでもキツいところは多い。

上記のAC数ランキングを見ると分かるけど、TypeScript を使って2000ACを超えているようなガチ勢はいない。これが向いていない事実を端的に表していると思う。

以下に、自分が思ったポイントを記す。

向いているところ

柔軟なデータ構造

例えばオブジェクト型をサクッと使えるし、配列やタプルもまぁまぁ使いやすい。Set なんかもデフォルトで存在するので、色々できる。

一時期、Go で書いてみたことがあるけど、このあたりが厳しかった。

メモリ周りを気にしなくて良い

GCがあるので、メモリ周りは任せられる。Rust のように所有権で困ることがない。まぁ競プロではメモリ解放せずにメモリリーク上等みたいな手法が常套なので、そもそもあまり気にしないところではあるけど。

向いていないところ

number型

これが一番キツい。

まず、整数型と浮動小数点型の区別がない。整数同士を除算したら小数点以下の値を持ったりするので注意する必要がある。そんなときは Math.trunc() が大活躍する。

そして整数の最大値が結構小さいNumber.MAX_SAFE_INTEGER で取得できるけど、これが 2^53 - 1、つまり 9007199254740991 で大体 9 * 10^15 程度なので、少し大きな値を扱うとオーバーする。そんなときは BigInt を使うことになるけど、演算するときは 1n みたいに n を付ける必要があるし、何よりかなり遅いのでとても困る。

多次元配列の初期化が面倒

1次元配列に数値を入れるような場合だと Array.fill() を使って一気に初期化できるものの、2次元配列になると1つ1つ array.push([]) で追加していく必要がある。配列を一気に fill([]) すると、全てが同じ配列を見てしまうので。

まぁテンプレを作ってコピペすれば解決する程度の問題ではある。

その他

実行速度が遅いとか、メモリを食いまくるとかは、言語設計的に仕方のないところ。

他には、Deque がないので Array を使うと先頭要素の操作が遅いとか、Array.sort() がデフォルトでは文字列比較でソートする罠があるとか、言い出せばキリがない。

競プロについて思うこと

競プロは筋トレと同じ基礎トレーニングだと思う。どうも競プロ偏重の風潮がある気がするけど、あくまでもプログラミングの一部。もちろん競プロはプログラミング力向上に役立ちはするけど、筋トレだけしていてもサッカーが上手くならないのと同じように、色々なことをやる必要がある。

実のところ、個人的に競プロはそんなに好きではない。今の競プロは競技性を突き詰めるあまり、先鋭化しすぎている気がする。高度な数学の知識がないと解けない問題とか、「それって最早プログラミングで競ってないよね」と。競プロ界隈には全然詳しくないけど、偏った方向に濃縮が進みすぎている感がある。

まぁ、数学の知識があるに越したことはないのは紛れもない事実。筋トレでベンチプレスの数値向上を目指すのと同じように、競プロのレーティングを上げていくのは一種の「競技」としてはアリ。でもそれだけで何かを生み出せるわけではない。

とは言え、競プロは初心者の入り口としては良いと思う。基礎中の基礎である「プログラミングがどういうものか」を学ぶときに、適当な難度の課題が与えられるのはちょうど良い。

個人的には、その先の指標になるものが何かあればいいと思っている。実際に何かプロダクトを作るのはあるにしろ、それでは評価が難しい。ISUCON は総合力の局地だけど、競プロと ISUCON の間を埋めるようなものがあるとIT業界がもっと発展していくような気がする。例えばコードの保守性や、コンピュータサイエンスの幅広い知識、仕様を考える力、ツールやライブラリの使い方などなど。情報処理技術者試験はあるけど、あれは知識に偏りすぎているので、もうちょっとスマートで面白いものがあればいいな、と。誰かにそんなサービスを作って欲しい。(他力本願)

最後

とりあえず TypeScript で AtCoder をやるのは満足した。今後、競プロを真面目にやるなら Rust かな、という感じではある。これまで一番しっかり勉強した言語だし。(でも Rust なんも分からん)

あと、今度の言語アップデートで入る予定の Zig にも注目しているけど、安定化が2年後くらいの目標で、色々と揃っていくまでもう少し時間がかかることを考えると、本格的に手を出すのはもう少ししてからでいいかも、と思っている。

まぁ多分、競プロではなく、TypeScript を使ってなんか適当なシステムを作っているかも。最近の Next.js はかなり良いし。

ちなみに色々と偉そうに書いてきたけど、実は自分の AtCoder のレーティングは灰色……というか1回もコンテストに参加したことがなくスコア0なので、話半分に聞いて欲しい。コンテストを土曜の夜とかにやられても、趣味(登山とサイクリング)の関係でほとんど家にいないし、家にいたとしても寝ているので物理的に参加できないとかの釈明はあるけど、弱々なのは間違いない。