初めてAt Coder Heuristicに参加した反省
1/10にAt coder heuristicに初めて参加した反省を書こうと思います。ぶっつけ本番で挑んでしまったため、勉強や準備が全くできていませんでした。
これは私個人の経験ですが、役に立つことがあれば幸いです!
この記事の中の考えた手法は、ほぼ全て実用的ではない自覚があります。私はぶっつけ本番で挑んでしまったので、焼きなまし法すら知りませんでした。ですので、この内容に惑わされないようにご注意ください。
1/10 15:00 ~ 19:00の間の時間配分
今回は初回ということもあって特に時間配分を意識することはありませんでした。今回のコンペの提出結果は下の表のようになっています。
| 提出日時 | 問題 | 言語 | 得点 | コード長 | 結果 | 実行時間 | メモリ |
|---|---|---|---|---|---|---|---|
| 2026-01-10 18:57:49 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 2022221 | 14066 Byte | AC | 79 ms | 11312 KiB |
| 2026-01-10 18:51:39 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 0 | 16285 Byte | RE | 517 ms | 12616 KiB |
| 2026-01-10 18:23:07 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 2022221 | 17806 Byte | AC | 78 ms | 11612 KiB |
| 2026-01-10 18:17:28 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 59400 | 17805 Byte | AC | 83 ms | 11556 KiB |
| 2026-01-10 18:08:20 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 2022221 | 10572 Byte | AC | 80 ms | 11200 KiB |
| 2026-01-10 18:02:18 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 2054 | 13092 Byte | AC | 93 ms | 11356 KiB |
| 2026-01-10 17:57:17 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 0 | 15972 Byte | TLE | > 2000 ms | 11348 KiB |
| 2026-01-10 17:49:02 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 1989993 | 9431 Byte | AC | 71 ms | 11100 KiB |
| 2026-01-10 17:41:31 | A - Stack to Match Pairs | Python (CPython 3.13.7) | 0 | 17028 Byte | TLE | > 2000 ms | 11420 KiB |
15:15~17:41 初回の提出まで
この間はClaudeと対話をしながら自分の考えた探索方法を詰め、それを実装するしようとしていました。2:30も方法を見つけるのにかけてしまったのは、どう考えても時間配分が正しくないと思います。 この間に考えた手法は以下のようになります。
1.蛇のように探索する手法
これは一番最初に思いついた手法で、一番左上のマスから右、下、左、下、右、右、上、上、右...というように蛇行をしながらすべてのマスを通り、その間に同じ文字があれば回収して消去する方法です。また、この蛇行が迂回になってしまっている場合には、ショートカットしても良いというようにしました。(そのほか、幾つか場合分けがありますが、結局そのまま実装することはなかったので割愛します)
2.空白の領域を拡大する手法
人間の血管のように、「大通り」とその周りの「小さな道」に分けて移動する手法。
これは、例えば、6 * 6の場合には、(1,1),(1,2),(1,3),(1,4),(2,4),(3,4),(4,4),(4,3),(4,2),(4,1),(3,1),(2,1) ...というようにグリッド全体を大体通るような道を「大通り」とし、その周辺のマスはこの大通りから派生した道を通るように移動する手法です。こちらに関しても、結局実装することはなかったので詳細は割愛します。
3.マンハッタン距離を考慮して下の評価式を最小にする方法で移動するもの
「- 空きマスの増加量 * 2 + 移動コスト - マンハッタン距離の総合減少量」
ここで、マンハッタン距離の総合減少量とは、同じ文字の間のマンハッタン距離(これは1枚目が(i,j),2枚目が(l,m)にあるとするとき、|i-l|+|j-m|の値をそれぞれの数字で足したものです。最終的にはこの評価式を使おうとしていました。
これらの発想をする中で役に立ったのは、Claudeに投げてインタラクティブに動作するゲームを作ってもらったことでした。これがあったことで実験が容易になり、整数論で小さな数値を代入して傾向を掴むというようなことがしやすくなったと思います。
問題は、ここから編み出された発想は小さい数値でしか有効でない、一般性がない方法になっている可能性がある点です。
ここまでの問題点
しかし、私のアプローチには決定的な問題点があります。それは計算量を全く考慮していないということです。アイディアベースのトップダウン的な手法だと、それが実際に使えるかどうか全くわかりません。今回参加した一番の問題点は、ボトムアップの設計を全くできなかったため、ここまで出してきたアイディアは、結局ほぼ全て没になってしまいました。
おそらく、具体的なコードを書かせるのに関しては、生成AIに任せても良いと思うのですが、人間側はその設計を全て理解し、(条件分岐も漏れなくすべてできていることを確認し)その上でオーダー評価を適切にし問題がないことを確認したうえで実装する必要があるのだと考えました。そして必要に応じて中身を生成AIの助けを借りることなく書き換えることができるぐらいのプログラミング能力がないと、調整が難しくなると思います。オーダー評価をするためには、条件分岐をおそらく全て把握しないと厳しいため、計算量の評価ができるようにすることをひとまず目標にしたいと思います。
17:41~17:49まで
17:41で計算量が爆発してしまったようなので、ここでまずは今までの方針を全て撤回し、最も単純な方法で提出をすることになりました。(これは後でClaudeでこのように判断したことがわかりました。)その結果が、1989993 点のものです。
17:49~19:00まで
ここから先は、自分のアイディアを、実現可能な範囲で導入することを目的としました。しかし、今回の最高点2022221 点をみれば分かるように、ほとんどこれは実現しませんでした。唯一導入できたのは、「- 空きマスの増加量 * 2 + 移動コスト - マンハッタン距離の総合減少量」という良くわからない評価式を部分的に導入することです。
原因の推測
どのように自分のアイディアを実装するかの具体的な設計をすることはしなかったため、完全にClaudeまかせになってしまったのが原因だと思います。繰り返しますが、条件分岐や具体的な処理内容に関しては人間側が理解をし、その上で計算量は把握していないと、実現可能か否かは全てAIに頼り切ってしまうことになるため、ここは絶対に克服しないといけない課題です。AIの存在意義は、おそらく効率化以上のものではなく、設計をするところなどで手を抜いてしまうと、中身がブラックボックスになり、人間側が介入できる範囲が制限され、思ったように結果を伸ばすことはできません。
今後の設計の方針
ここから先に記すことは予想でしかないのですが、おそらくこれからは、計算量をベースにしたボトムアップの方針を基盤に据え、可能であれば計算量などは全て管理できるような状態のまま、思いついたアイディアを導入することになるのだと思います。ここでトップダウンのアイディアに関しては、ボトムアップの設計が絶対に必要なのに対して任意です。もしかしたら、今後AHCの勉強を進めていったら不必要になるのかもしれません。
そして、これも憶測でしかないのですが、大まかな設計のアイディアに関してはある程度早めに決めた上で(ここまでである程度の点数が出ている必要があります。)、ハイパーパラメータの調整にうつり、細部の調整を進めることで徐々に点数を上げるのが正しい流れになるのかと考えました。
それを踏まえて、時間配分と提出の状況は、次の表のようになることを次回は目指そうと思います。但し、得点は最後に提出したものを基準として1に調整します。また、ハイパラを調整する段階がもしなければこの時間配分は変わりえます。
| 時間 | 得点 |
|---|---|
| 最初の設計(1時間)→ (この段階では拘らずに確実に基準を満たせるようにする) | |
| 一回目の提出(1:00) | 0.7 |
| 別設計も含めて幾つか試す(1時間) | |
| 二回目の提出(1:30) | 0.8 |
| 三回目の提出(2:00) | 0.75 |
| ここまでの複数の設計をもとにして、どの手法を採用するかを決める(10分) | |
| 採用する手法をさらに改良を進める(50分) | |
| 四回目の提出(2:40) | 0.85 |
| 五回目の提出(3:00) | 0.9 |
| ハイパーパラメータの調整(1時間) | |
| 六回目の提出(3:20) | 0.92 |
| 七回目の提出(3:40) | 0.97 |
| 八回目の提出(3:50) | 1.0 |
次回へ向けてのTodo
1.まずは勉強と下準備を終えること
・焼きなまし法など基礎的な知識を知らずに得点を伸ばすのは不可能だと考えるので、まずここの勉強を進めます。
・また、今回は実験をするためには提出してその結果から判断するしかなかったのですが、これは非効率的で得られるフィードバックも、点数、ACやTLEなどの情報などに限られてしまっているので、実験環境を整備する必要があるでしょう。
2.今回のコンペの問題を通してすること
・コンペ後も学習教材としてこの問題を使用して勉強しようと思います。1.で学習したことの実践の場とします。
・↑生成AIを使用するか否かも含めて、そこらへんの調整を進めようと思います。
Discussion