TERRYのブログ

最近は競技プログラミングにお熱。

AtCoder World Tour Finals 2025 Heuristic 参加記

2025/7/16に行われたAtCoder World Tour Finals 2025 (AWTF 2025) のHeuristic部門に参加して、準優勝🥈することができました。自分でも信じられない結果で、本当に嬉しく思います。

世界大会に出て準優勝するなんて滅多にない経験なので、参加記を書いてみます。

🥈銀メダル🥈

AtCoder World Tour Finals 2025とは

そもそもAWTFとは、競技プログラミングの世界一を決める、AtCoder主催の年に一度の世界大会です。

昨年まではAlgorithm部門だけだったのですが、今年からHeuristic部門が追加され、2部門それぞれで世界一が競われます。

詳細については以下のAtCoder Infoのサイトをご参照ください。

info.atcoder.jp

2024年

ATWFの参加権は前年のAHC (AtCoder Heuristic Contest) の成績によって決まります。AHCで30位以上に入ると順位に応じてGP30と呼ばれるポイントが得られ、年間を通したGP30合計値の上位12名がAWTFへの参加権を得られます。*1*2

2024年はAHCで2回優勝するなどかなり調子が良く、1位で通過することができました。

2024年シーズン GP30

2025年

だいぶ早い段階に通過の案内が来て、いろいろなアンケートに答えるなどしていました。

アンケートで答えたプロフィールは、AWTF直前にこちらのページに公開されました。ありがたいことにsoumatさんに「尊敬している競技プログラマー」として挙げられていたようで、かなり恐縮していました。

info.atcoder.jp

また直前になって、OpenAIがAWTFのスポンサーとなり、「人間 vs AI」のエキシビションマッチが開催されるということも発表されました。この件についてはコンテスタント側も聞かされていなかったのでかなりびっくりしていました。この少し前に発表されたALE-Agentの性能を見ると負ける可能性は低いかなと思いつつも、わざわざスポンサーとなってエキシビションマッチに参加するということはそれなりに自信もあるはずで、一体自分たちは何と戦わされるのかとビクビクしていました。

prtimes.jp

Day 0 (コンテスト前日)

コンテストが平日9時スタートで、自宅からだと起きる時間が早くなりすぎるのと、通勤ラッシュに巻き込まれてしまうことから、前日からホテルに泊まらせてもらいました。

マイ枕を持参して22時半頃には布団に入ったのですが、無事0時半頃に目が覚めて破滅の予感がしてきます。

2時頃には眠れたようです。応援してくれた人ありがとう……。

Day 1 (Heuristic部門)

起床~会場入り

無事6時前の起床に成功します。

熱などはないのですが鼻水が無限に出て、正直体調は万全ではなかったのですが、海外勢に比べればだいぶマシなコンディションだったと思います。午前9時スタートは欧州だと午前0時スタート相当ですからね……。

ホテルではビュッフェ形式の朝食が出ました。昼ご飯を食べる暇がない予感がしたので、とりあえずおなかいっぱい食べました。おいしかったです。*3

ホテルから会場まではバスで移動したのですが、バスの降車位置から会場までそれなりに歩き、しかも大雨が降ってきたので大変でした。たまたま普通の傘と折りたたみ傘の2本を持っていたので、海外勢に片方貸すなどしていました。

コンテスト開始前

会場に到着すると、机の上にいろいろお土産が置いてありました。

  • Tシャツ 通常 ver.
  • Tシャツ OpenAI ver.
  • 名札
  • AtCoderトートバッグ
  • AWTFうちわ
  • 謎の順列カード

Tシャツは2着とも概ね柄が同じで、OpenAIバージョンは前側にワンポイントでOpenAIのロゴが付いていました。AWTFのロゴがめちゃくちゃ格好良くてテンション上がります。もったいなくて着られなさそう……。

Tシャツ

名札

AWTFうちわ

謎の順列カード、本当に謎でした。「コンテスト中に使うのでは?」「懇親会で使うのでは?」などとさまざまな憶測がなされましたが、結局最後まで一切説明されず、謎です。

謎の順列カード

ノートPCがPコア6個しかなく、ローカル実行するとコンテスト中のテスト実行が遅くなりそうなので、Google CloudのCompute Engineで16コアインスタンスを事前に起動しておきます。*4

机を並べ替えたりだらだらしたりChatGPTとコントをしたりして、コンテスト開始を待ちました。

この日ChatGPTを使った唯一のシーン

コンテスト中

コンテストの様子はYouTubeで配信されました。

www.youtube.com

実況がしやすいよう、自分自身がコンテンツになるぞ!という気持ちで、画像のような感じで考察メモを出しっぱなしにして参加しました。配信中に拾ってもらえたようで良かったです。

VSCode画面

序盤は解法を決め打たず、とりあえずぐだぐだ考察していました。色々考えた結果「よく分からないな……」となり、とりあえずClaude Sonnet 4くんに愚直な個別命令解法を書かせて感触を見るなどしていました。その後ビムサを書いてみたのですが、振動しだしたのでダメだこりゃとなって捨てました。

中盤は方向別にクラスタリングした上で、グループごとの動きや壁を焼きなましていました。一瞬1位を取ったりはしましたが、そこから伸びるビジョンがあまり見えず苦しんでいました。焼きなましの実行時間を伸ばせばスコアが伸びることは分かっていたのですが、計算量を落とせる見込みはあまりありません。ならば良いルールベースをということで、長時間焼きなましが吐き出した解から何か読み取ろうとしても、「焼きなましが天才過ぎて何も分からない……」となっていました。

中盤以降もOpenAIが頭打ちにならず解法の改善を続けていたのは正直なところ想定外で、「OpenAI凄いなあ……」となっていました。手元のcopilotはおよそ常識では考えられないようなバグを埋め込みまくっているのに……。

自分の解法の下界を達成したときのスコアをコンソールに吐き出させていたらそれが実況のchokudaiさんに拾われてしまい、なんだか無駄に期待させてしまったようです。*5 下界を達成してもギリ勝てるくらいだったのであまり解法の筋は良くなかったのですが、じゃあここで方針転換するかというとなかなか難しいところですね……。

1位を取るとイルカの風船が席に設置されるのですが、「なんか集中力削がれるなー」と思って考察ノートに書いたら対応していただけて、かなりありがたかったです。変に文句言っちゃったかな?と思いましたが、後から配信を見たら自分の思っていた以上に風船が揺れまくってて笑いました。*6

終盤は解法を切り替える時間がなくなったので、優勝狙いは諦めて2位狙いに切り替えて、高速化やパラメータチューニングなどをしていました。全体的にバグらせまくってかなり辛かったのですが、ギリギリパラメータ調整まで終えることができました。

コンテスト中はランチボックスやサンドイッチなどいろいろ提供されていたのですが、1秒でも実装時間を確保したかったので結局食べる暇がありませんでした。まあ半分予想通りではあります。

結果としてPsyhoさん・OpenAIには及ばず、エキシビション順位表で3位となりました。まあこのメンツでこの順位は上出来ではあるのですが、この時点ではあまり勝った気分にはなれずという感じでした。

コンテスト中のメモはこちらに書いています。苦しかった……。

github.com

コンテスト後

疲労困憊であまり記憶がありませんが、寿司を食べていたようです。

ちなみに今回の問題はAHC writerとしての原案に似たようなものを考えていたことがあったのですが、上手く問題にできずにボツにしていました。もう少し頑張ってくれ!

Day 2 (Algorithm部門)

起床~観戦

自分の出番は終わったので、気楽に観戦できる状況になりました。日本勢からはhos_lyricさん・noshi91さんが出場されるので、のんびり応援していきます。

日本語配信はゲストルームと同じ部屋の中で行われており、目の前でchokudaiさんが喋っててちょっと面白かったです。Heuristic勢と一緒に問題を読んで???となったり、chokudaiさん・tester陣の配信を聞きながらわちゃわちゃしたり、zhoukangyangさんが4完しているのを見てすげー!となったりしました。

表彰式

暫定テストの段階で1位-2位-3位間のスコアはそれなりに離れていたので、システムテストでひっくり返る可能性は良くも悪くも低いかなと思っており、実際その通りになりました。コンテスタント中2位(OpenAIも入れると3位)です。

入賞者の中で多分英語力が一番低いので、受賞コメントは中学生英語みたいな感じになりました。ちゃんと事前にコメントを考えておけという話なのですが……。あまりに中学生英語すぎたためか日本語でもコメントしてくれと言われたので、日本語でちょっと長めに喋るなどしました。

Psyhoさん vs OpenAIの結果が気になるところだったのですが、最終的に1割ほどの差を付けてPsyhoさんが勝っていてかなり盛り上がりました。人類最後の砦となってくれてありがとうございます……!

このほか、準優勝パネルをエキシビション2位だったOpenAIの人に渡して笑いを取るなどしました。

準優勝パネル

懇親会

表彰式終了後、バスで懇親会会場に移動しました。卓球・ダーツ・ビリヤードなどで遊べる会場で、例年ここで懇親会を行っているようです。

Algorithm部門の中国勢に「Heuristic部門で重要なテクニックは何?」と聞かれたのですが、「焼きなましやビームサーチなどのテクニックはあるけど、一番重要なのはトライアンドエラーだよ。コードを書いて、ビジュアライザを見て、何が良くないかを見て改善するんだ。」みたいなことを英語で言ったら何か伝わってそうなのでセーフでした。

Psyhoさん・nikaさん・Rafbillさんといった海外のレジェンド勢とも交流を試みました。うまく喋れないのでほとんど聞き役だったのですが、解法に至るまでの考察等を直接聞くことができ、とても良い経験になりました。来年は英語力を付けてもっと交流できるようになりたいところ……!

AWTFケーキ

帰宅

懇親会も終わり、帰路についたところでなんだか急に準優勝の実感が湧いてきました。大会中は現実感がなかったのですが、改めて考えると競プロを始めてから5年、あのレジェンド勢の中で2位を取れたんだなあ……と。

六畳一間の魔女ライフを読んでください。

解法

解法を簡単にまとめておくと、最終的に以下のような流れで解きました。

  1. クラスタ数を2~10まで全探索してそれぞれでクラスタの焼きなましを行い、一番良かったものを選ぶ
  2. 操作列・壁・クラスタ・貪欲順をまとめて焼きなまし

1ステップ目のクラスタの焼きなましでは、各ロボットの移動ベクトルを考えて、その移動ベクトルが似たものが同じクラスタに入るように焼きなましをしました。具体的な評価関数は、クラスタごとに (移動ベクトルの平均値のマンハッタン距離) + (個別のロボットが残り移動しなければならないマンハッタン距離の合計) として、その総和を取りました。

2ステップ目の焼きなましでは、操作列を途中までシミュレートしたあと、1個ずつBFSを行って移動させた合計の手数を評価関数としました。 10^4 オーダーくらいしか回らず高速化すると伸びることは分かっていたので、盤面を32bit整数30個の01bitで表して、BFSをビット演算で行うbitboard高速化したところまでで力尽きました。

感想

前述の通りAWTFが終わるまでは負けた悔しさの方が勝っていたのですが、AWTFが終わって現実に戻ったタイミングで急に嬉しさがこみ上げて来ました。10時間という短い時間のコンテストだったとはいえ、あのレジェンド勢の中で準優勝を勝ち取れたのはものすごく嬉しいですし、今後の自分の自信にもなるなと感じています。

コンテスト中の立ち回りを振り返ると、解法の選択については反省点があるなと感じています。自分の解法は無難な解法ではあるのですが、優勝を狙える解法ではないんですよね。wataさんがAWTFに出すくらいの問題なので、重要な気付きを得ないと優勝レベルの解法に辿り着けないとコンテスト中にも思ってはいたのですが、諸々のプレッシャーがかかる中でなかなか大一番でそういった思い切った立ち回りはできなかったなあ……と感じています。このあたりはこういう舞台の経験不足もありそうですが、今回2位を取ることはできたので、次は順位の期待値を最小化するのではなく、優勝確率最大化狙いで大胆な立ち回りをするのも良いかもしれません。

あとから配信を見たのですが、競プロの配信としてかなり完成形に近いものになっていたように思います。10時間配信ってどうなるんだ……?と思っていましたが、見てみると企業対抗Team Battleからさらに進化していて、非常に面白いものになっていて凄いな……となっていました。自分もリアルタイムで観戦したかったくらいです。

今回はエキシビションでOpenAIと併走することになりましたが、負けたくないというプレッシャーはありつつも、AIの点数が「目指すべきスコア」として序盤から出てくるので、体験としては悪くなかったなという印象です。誰か(montplusaさんかな?)の言葉を借りるならマラソンのペースメーカー的な感じで、その点数を出さないといけないという前提で解法を考えることができたなあという印象です。コンテスト中はずっとエキシビション順位表ばかり見てましたしね。

また、正直現状のAIがここまでできるとは思っていなかったのでとても驚きました。終盤まで頭打ちにならず継続してスコアを伸ばし続けていたのが印象的でしたね。AIは1つの解法をカリカリにチューニングして突き詰める力が強いようで、今回の立ち回りのようにAIと同じ解法方針になってしまうと勝てないなという気持ちになりました。こういう大舞台に自社のAIモデルを参加させることはプレッシャーもあると思うのですが、その中で手を挙げて参戦して、なおかつ結果を残したOpenAIに拍手を送りたいと思います。

一方で全く違う解法を取っていたPsyhoさんが勝っていたり、コンテスト後にRafbillさんが倍以上スコアを伸ばしていたりするのを見ると、特に長期のコンテストだとまだ人間が勝てる余地は十分ありそうに思えます。今後AIがさらに伸びて、長期コンテストでも人間を超える日が来るのが楽しみです。

最後に、とても面白い問題を作成してくださったwataさん、実況で盛り上げてくださったchokudaiさん、配信を見てくださった視聴者の皆さん、ヤバいくらい強かったコンテスタントの皆さん、スポンサーおよびエキシビション参加をしてくださったOpenAIの皆さん、開催のずっと前から準備をしてくださったAtCoderの皆さん、本当に素晴らしいコンテストをありがとうございました!来年も参加できるように頑張ります!

*1:GP30のルール詳細 → AtCoder World Tour Finals 2025開催のお知らせ - AtCoder

*2:GP30が何の略なのか自分は未だに分かっていません。

*3:この立ち回りは後から見ても正解でした。

*4:16コア = 32vCPU インスタンスをasia-northeast1で10時間借りたところ、3000円ほどになりました。

*5:配信の5:51:30あたりなど。

*6:配信の6:01:30あたり。