先日PHPerKaigi 2025 PHPerコードバトル 予選 - connpass に参加しました。その際の感想を書きます。
参加するまでの経緯
正直私は「PHPerコードバトル」が何なのか「コードの何でバトルをするのか」もよくわからず、PHPも得意というわけでもなかったのでイベントを知ったところで参加するつもりはなかったですが、 asumikam さんが「一緒に参加しよう!」と誘ってくれたのをきっかけに勢いで登録しました。
説明を読む限りはいわゆる「コードゴルフ」のような、コードの行数を削ることを競うイベントだと理解しました。私は一度もコードゴルフ的な大会に参加したことはなかったですが、とりあえず参加してみて楽しもうということで気軽に挑みました。
PHPerコードバトルはお題で指示された動作をするPHPコードをより短く書けた方が勝ち、という競技です。 お題は決して難しいものではなく、少し練習すればPHPerプログラマであればどなたでも参加できる難易度を目指しています。 https://phperkaigi.connpass.com/event/346294/
事前準備
1行も書けない状態だと恥ずかしいなと思って、事前にPHPのマニュアルを軽く眺めて文法を確認したり、手元にPHPのコードを適当に書いておくためのディレクトリを掘っておいたりしました。
asumikam さんがChatGPTに色々コードゴルフテクニックを聞いているという話をしてたので、私も真似してChatGPTに聞いた上で以下のメモを手元にこさえました。
// arrow function
// instead of function($x) { return $x * $x; }
fn($x) => $x * $x;
// Null合体代入演算子
// instead of if (!isset($a)) { $a = 'default'; }
$a ??= 'default';
// 三項演算子の省略形
// instead of $result = $value ? $value : 'default';
$result = $value ?: 'default';
// 複数変数の同時代入
// instead of $a = 10; $b = 10; $c = 10;
$a = $b = $c = 10;
// 条件分岐で単一のアクションのみを行う場合、and や or を使った短絡評価で記述を短くできる
// instead of if ($a) { exit; }
$a or exit;
function
を fn
で書くことができるアロー関数は絶対使えそうだなと思ったり、 $a or exit
はPerlの or die
を思い出すなとこの時点で思ったりしました。あとなるべく for {}
などの {}
を省略していきたいなと思ってみたり。
当日のシステム
「PHPerコードバトル」専用のWebサイトが用意されており、forteeのアカウントでログインして参加者は全員手元のPCから参加できる形になっていました。よくあるAtCoderなどのオンラインジャッジシステムと同様な形で、手元のエディタで書いたものを入力欄に貼り付けて提出したら点数(この場合はバイト数)が表示されるという感じでした。
予選ラウンドが3つありましたが、それぞれ参加者全員が同じ問題に同時に挑戦し、リアルタイムで参加者ごとのスコアがプロジェクターに投影されていて盛り上がりがありました。「上位のあの人はどうやってあんなスコアに辿り着いてるんだろう」と思いながら進めていって、終わった後は司会の人が回って本人にコードの解説をしてもらうという形で学びが多かったです。
私も意外といいスコアが出せて、無事予選通過しました 🎉
PHPerコードバトル予選通過しました😹 (4位までが通過)#phperkaigi pic.twitter.com/EADcCK6lHz
— すてにゃん (@stefafafan) March 8, 2025
手元のパソコンで好きなエディタやネットが使えることが個人的に大きくて、PHPに詳しくなくとも「この関数名長いから短い代替手段はないかな」とネットで調べたりGitHub Copilotに聞いたりしながら進めました。実際 str_repeat
を str_pad
で代用できることはStack Overflowで発見したり、 Copilotには file_get_contents('php://stdin')
のような書き方を教えてもらったりしました。
また、予選ラウンドが進むうちに上位陣の細かなテクニックを他にもリアルタイムに学ぶことができてそこも面白かったです。実際に使うことは叶いませんでしたが「繰り返し登場する関数名を文字列として変数に入れておいて使い回す」テクニックは、言われてみればPerlでも可能な手法だし利用できるなと学びを得ました。(PHPの array_*
的な関数ってどれも文字数が多いですね)
エキシビションマッチ
エキシビジョンマッチでは1位と4位、2位と3位が対決しました。私は2位通過ということだったので3位の方と対戦しました。
エキシビジョンマッチも予選ラウンドと同様にWebサイト上で対決でしたが、こちらは1対1なのと、観戦モードに入るとそれぞれが提出したコードがリアルタイムで確認できる仕様となっていました。プロジェクターに観戦モードの画面を写しつつ、選手はプロジェクターをバックにしてコードを書く形で非常にわかりやすくて盛り上がる構図になっていました。選手としても画面共有などの煩わしさが不要だし、細かな操作をみんなに見られるのは緊張感があるので、提出したコードだけが随時表示される仕様はありがたかったです。
結果的に私はエキシビジョンマッチでも3位の方に僅差で勝つことができてしまい、「まじか」という感じでした。Copilotに聞いて導き出したメソッドを利用したコードによって勝てたところが大きかったのでAI様様という感じでした(もしレギュレーション的にAIが利用不可であればそもそもここまで上手く勝ち進めなかったでしょう)。
その他感想
今回問題とは別にサンプル解答が毎回提示されており「まずはサンプル解答を提出して最低限のスコアを得ましょう」という進め方が案内されていました。これが非常によかったです。
日本語の問題文を読んだ上でゼロからコードを書く必要があるとしたらそれなりにハードルが高く、そもそもテストを通すことができずに時間切れになってしまう人も多いと思うので、「ベースラインとしては全員点数はゲットできる」というのは安心して挑めました。サンプルコードをベースに改善していく(変数名を縮めていくなどの簡単な改善も必ず存在する)というのがちょっとずつ成功体験が得られて嬉しかったです。
次回
今回リアルでの予選に参加し通過したので、次回はPHPerKaigi 2025のDay 0に開催されるPHPerコードバトル準々決勝に参加する予定です。準々決勝には「オンライン予選」通過者も参加できるそうなので、興味があって参加できなかった方はオンライン予選にもチャレンジしてみるといいかもしれません。1
この度は誘ってくれた asumikam さん、運営してくれたスタッフのみなさま、そして他の参加者のみなさまありがとうございました!
Footnotes
-
オンライン予選がいつどこで開催されるのか、詳細については公式Xの @phperkaigi をフォローしておくといいかもしれません。 ↩