AtCoderが、全くできない。
誇張ではない。
A問題で手が止まり、B問題で制約を読み間違え、C問題は最初から見ない。
コンテストが終わったあと、タイムラインに流れてくる「初参加でCまで解けました」とかいう報告を眺めながら、静かにブラウザを閉じる。
一方で私は何をしているかというと、
- 仕事ではGoやらRustやらを書いている
- TypeScriptでバックエンドやフロントエンドも書いている
- API設計もするし、コードレビューもする
- プログラミングで普通に給料をもらっている
いわゆる「業務ではコードを書いている人間」ではある。
それでもAtCoderは、全くできない。
先に断っておくこと
先に断っておくと、この記事はAtCoderや競技プログラミングを否定したい話ではない。
限られた時間で問題を読み、解法を見抜き、ミスなく実装しきる能力は、普通に考えてかなり高度だと思っているし、実際にできている人は素直にすごいと思う。
この記事は、「なぜ自分はそれができないのか」
を整理するための、ほぼ自己分析である。
結論:私は競技プログラミングができない
最初に結論を書く。
私はプログラミングができないのではなく、競技プログラミングができない。
この2つは似ているようで、実際にはかなり別物だ。
AtCoderは「アルゴリズムを思い出すゲーム」
AtCoderの問題を見て、毎回こう思う。
で、これは何を思い出せばいい問題なんだ?
業務でのプログラミングは、
- 要件を読む
- 仕様を整理する
- 必要なら調べる
- 試行錯誤しながら実装する
という流れが基本になる。
一方AtCoderは、
- 問題を読む
- 制約を見る
- 「あ、これは〇〇法だ」と気づく
- 実装する
という世界だ。
もちろん、これは「暗記ゲーだから簡単」という意味ではない。
むしろ逆で、大量の典型を理解したうえで、瞬時に引き出せること自体が一つの専門技能だと思っている。
ただ、私はその訓練をほぼしてこなかった。
業務で書くコードとAtCoderのコードは方向性が真逆
業務では、だいたいこんなことを言われる。
- 可読性が大事
- 保守性が大事
- 変数名はちゃんとつけろ
- 意味のある単位で関数を切れ
AtCoderのコードはどうか。
- 変数名は
i,j,k - 関数は
mainだけ - コメントはない
- とにかくACすれば正義
私はAtCoderでコードを書いていて、
これ、あとで読めないな……
と考えてしまう。
しかし「あとで」は来ない。来る前にTLEかWAで終わる。
制約条件を見ても、何もひらめかない
AtCoderの問題には、だいたいこう書いてある。
1 ≤ N ≤ 2×10^5
競プロができる人は、これを見てすぐに
- O(N log N) まで
- これは全探索は無理
と判断する。(のだと思う)
私はというと、
- 「2×10^5か……多いな……」
で思考が止まる。
業務では、
- 遅かったら直す
- キャッシュする
- そもそもそんな入力は来ない
で済んできた。
制約を見た瞬間に戦略を立てる訓練を、私はしていない。
実装スピードが足りない
業務では、コードは丁寧に書く。
- テストを書く
- ログを入れる
- エラーハンドリングを考える
AtCoderでは、そんなことをしている余裕はない。
特にGo。
- 標準入力が地味に面倒
-
bufio.NewReaderを毎回思い出す - 型変換で一瞬止まる
気づくと30分経っていて、問題はほぼ進んでいない。
AtCoderはスポーツに近い
最近思う。
AtCoderは、かなりスポーツに近い。
- 知識
- 反射神経
- パターン認識
- 制限時間内の判断力
これらを日常的に鍛えている人が強い。
私は何を鍛えてきたかというと、
- 設計を考える
- 仕様を詰める
- 将来の変更を想定する
- 人のコードを読む
使っている筋肉が違う。
だから、AtCoderが安定して解ける人を見ると、普通に「すごいな」と思っている。
自分にはない訓練を積んでいて、自分にはない判断力を持っている。
じゃあAtCoderができない私はダメなのか
別にダメではない、と思いたい。
- AtCoderが強い = 良いプロダクトが作れる、ではない
- AtCoderが弱い = 仕事ができない、でもない
ただし、
- アルゴリズムの引き出しが少ない
- 計算量への感覚が鈍い
という事実はある。
それを自覚したうえで、
- 競技プログラミングを頑張るのか
- 業務特化で生きるのか
選べばいいだけだと思っている。
まとめ
- 私はAtCoderが全くできない
- それでも毎日プログラミングをしている
- 競技プログラミングと業務プログラミングは、求められる能力が違う
- できない理由が分かると、少し気が楽になる
同じように、「仕事ではコードを書いているのに、AtCoderが全然解けない」という人がいたら、それは多分、あなただけではない。
少なくとも私がそうだからだ。
もし良い記事と思ったら、いいね、ストック、フォローお願いします🙇
おすすめ記事
Comments
こんにちは、私は過去のAtCoderプレイヤーで、現在は業務ITエンジニアをしています。
競技プログラミングと業務プログラミングの対比について考えることがたびたびあり、Xで見かけたこちらの投稿を興味深く読ませていただきました。
業務と競技で違う筋肉を使うという表現がお気に入りです!
私の感想で恐縮なのですが、業務プログラミングの流れに寄せて仕様整理のパートを入れると筋肉を活かせそうに思いました。
例えば問題文をもとに「数列から区間和を求める」「グラフから集合を求める」といった要件に整理できると、あとは調べながら実装の流れに持ち込めそうです!
私は制約をアルゴリズムの候補が複数出てきたときの判断材料の立ち位置で扱っていました。
コーディング文化の違いもあり苦労されると思いますが、応援しております!
(最近の問題の傾向を把握しきれておらず、的外れなコメントになっていましたらそっと見逃していただければです🙇)
@kagesan
ご丁寧にコメントいただきありがとうございます!
業務プログラミングの流れに寄せて仕様整理を意識するという視点、とても腑に落ちました。
温かい応援のお言葉までいただき、感謝申し上げます!!
面白く読みました
自分(青)の場合、記事で話題にあがってるABCのC問題とかまでなら、別に制約条件は意識しないかなと思いました。
最初の方の問題ならTLE/MLEに充分余裕を持った設定になっていることが多く、制約条件からアルゴリズム選ぶのはミスリードになることのほうが多いのでノイズだと思っています。
考察の足しになれば。
仲間
私も競プロ始めた当初は同じ感想を抱いていました。
総合して、競プロに継続して取り組んでいますと、「実装お祈り+反復改善」から「発想の反復改善+実装」にワークフローが変異したなと思ってます。
AtCoderに強ければ、間違いなく、思考の仕方は、効率の良い方向へと変化します。瞬発力と持続力のどちらも叶えるモデルの構築にあるので。
これは、最終的には頭の使い方の慣れだと思うので、決して自分とは合わないからなどと切り捨てるのではなく、改善目指してがんばってほしいと思います。
また、断っておくと、競プロは知っているアルゴリズムを全通り試して置きにいくゲームではありません。どちらかと言えば、問題構造を把握することで、シミュレーションから如何に演算量を落とす工夫をできる余地があるかを探すことが趣旨にあると思っています。
B問題までは、その落とす工夫というものが必要ないため、解けるという直感に至りやすいのではないでしょうか?
極論を言えば、何のアルゴリズムの事前知識がなくてもABCのE問題程度までなら挑戦できます。
私はわりと麺類が好きでよく食べてますが,だからといって他者から「普段そばとか結構食ってるんだから,わんこそば150杯はいけるよね?」とか期待されないと思います.
私自身としても,麺を効率的にたくさん食う技術(?)が己に欠如しているからといって「俺はダメなやつだ…」とか嘆いたりしませんが,
仮に,私が「200 杯くらいは余裕でいけないと……」とか思ってる人であれば,ギリで100行けるかどうかという己の現状を「ダメ」と評価するのでしょう.
(競プロ っていうか,「競技」ってなんかそんな.)
oh,,,my family❤️
Atcoder系は、数学の受験に近いと考えています。
まず、概念的な部分(数式・・アルゴリズム)を脳に叩き込んでおいて、類似問題をたくさん解く(量を捌いていく)スタイルが、かなり受験勉強と近いかなーと
競技プログラミング強い人は一般的に学生時の数学の成績が強い傾向があるようなないような。。
実は「あ、これは〇〇法だ」と気づくってのが必要なのは実はD問題から(まれにC問題から)なんですよ
読んでいて、マラソンの速い人と野球の上手い人の違いにすぎないような気がしました
@bkh4149 そういう記事ですので…
はじめまして。私も業務プログラミングで生計を立てている者です。貴方と同じで競技プログラミングは苦手、というか、私の場合は興味がそもそもありません。子供の頃からアセンブラやBASICやCなどで遊んでいたので、その延長でたまたまITブームに乗っかってプログラマーを続けているだけなので、実は業務プログラミングにも興味がないです。日々、海外の最新のプログラミング技術情報やライブラリなど追って、日本語の記事にしてくださっている方々を尊敬し、感謝しています。
今後はAIのバイブコーディングが当たり前になるので、業務プログラミングという世界や下流工程の人間のプログラマーの需要が消滅していくでしょう。とはいえ、人間が業務効率化のための自動システムを欲しがるのは変わらないため、それを作る仕事そのものはしばらく残ると思います(それでも上流工程の作業もいつかはAIが担当するでしょうね)
そのときは人間が可読出来る高級言語でプログラミングすることではなく、誰が読んでも理解しやすい自然言語の文章で要件定義だけすればいい時代、それが業務として求められる世界になると思います。遅くても2030年にはそうなっていそう、と思っています。その時に必要なのは高度なプログラミング能力ではなく、わかりやすく他人に伝える説明力かと思います。
そもそも業務プログラミングはAIの得意中の得意な分野ですから、可読可能なプログラミングである必要もなく、ブラックボックスになっても構いませんし、AIにとって都合のよい言語の方がシステム開発の効率も上がり、動作の安定性も見込めるのでは?と。というか既にAIにとって都合のよい言語はちらほら出てきていますね。粋(Sui)という名の言語で、日本人が開発しています。PCWatchの記事をチラ見したとき、言語形態や開発者の思想から、アセンブラを思い出して懐かしくなりました。
かつてアセンブラなどのCPUに優しく無駄なく高速動作するが、人間の可読性に関してはとても厳しい低級言語でプログラミングしていた時代は、とにかく人を選ぶものでしたが、もう少しマシにしよう、誰でも保守開発できるようにしよう、という考え方でBASICなどが生まれました。その後、更に高級言語としてCが生まれ、これはLinux系シェルを含め、現代のプログラミング言語の源流のような状態になりました。
しかし、当初はCPUが非力だったため、手練れのアセンブラプログラマーからは、ロートル向けの無駄で動作の遅い言語と嫌われていました。しかし今は、CPUの進化でアセンブラで書く必要がなくなったため、保守性や可読性や効率が重視され、それらが業務プログラミングでは当たり前になった、ただそれだけの話だと思っています。
人間がプログラミングするようになった世界も、なんだかんだでもうすぐ半世紀。人間並みに賢いAIが登場した現在、そろそろ文化や風習という形で古い概念に変わっていってもおかしくないです。人手不足・資金不足・技術不足、つまりヒトカネモノ不足で困っている会社・世界になるほど、AIに任せた方が良いと思っています。
AIに業務プログラミングの仕事が奪われた後の世界では、人間のやることがなくなって暇になるため、競技プログラミングだけが残ると思います。剣道とか書道とかそろばんとか、日頃の仕事の役には立たないけど、文化として残っている習い事と同じ運命をたどるはずなので、その時は、意識的に意欲的に競技プログラミングをやりたい人だけがやる、そういう世界になると思いますし、それでいいと思います。
Me too
Let's comment your feelings that are more than good