BsBsこうしょう

これは考えたことではなく思ったことです。

OUPC2021 開催記

去る4月3日、AOJ上で(大阪大学の競プロerの集まりがRAINBOUとなってから)2度目となる学内コンテスト、OUPC2021を開催しました。

https://onlinejudge.u-aizu.ac.jp/beta/room.html#OUPC2021/info

私は、その中で全体の取りまとめ役かつB問題(Longest Match)のwriterを務めました。この記事は、OUPC2021の経緯を振り返りつつ、その中で得た知見・裏話をまとめます。

まず、こちらのツイートをご覧ください。

これを見た競プロerに詳しい人は、「なぜレートも実力も一番高いはずのkotamanegiがwriterでもない訳分からんポジションにいるのか」と思うはずです。またこの記事をここまで読んだ段階でも、「なぜレートも実力も一番高いはずのkotamanegiがリーダーではないのか」と思われるかもしれません。この理由と効果についてお話しますが、それを話すにはOUPC2021の経緯に触れる必要があります。

OUPC2021開催の経緯

始動前夜〜頓挫まで

まず、OUPC2021の企画は2021年の5月頭に始まりました。私は競プロに触れなくなって長かったこと、前回OUPC2020で失敗してしまった経験から、OUPC2021には参加しないことを決めていました。当時はkotamanegiが全体のリーダーで、15人ほどのメンバーを集めることに成功したようです。

しかし、その後OUPC2021は完全にストップします。原案が考えられた形跡はいくつか残されていますが、現在私からは参照することができず、チームに入った時にもなかったので、そもそも原案の文書化もされてなかったと推測しています。

進展がないまま8月まで散発的にチャンネルに投稿がありましたが、その後は11月に私が入るまで完全に停滞します。

Badlyluckyが入ってから

11月頃にOUPC2021が大変な状況になっていることをkotamanegiから聞き、事態を打開するためにOUPC2021のチームに加入することになりました。しかし入ったら上記の有様だったので、開催するためには抜本的なやり直しが必要なことは明白でした。そこで、自分の仕事を2パターンのどちらかであると分析し、残っているメンバーに聞きました。

  • OUPC2021を、どんな形になってもいいから開催にまで漕ぎ着けること
  • OUPC2021の企画自体をボツにし、2021としての開催を断念すること(敗戦処理)

どちらも大事な仕事ですが、残ってるメンバーの回答から、私の仕事は前者に決まりました。しかし、5月時点でwriter希望を出した人で残っているメンバーはわずか2人であり、絶望的な状況に変わりないです。そこで残っているメンバーの中で新たにwriter希望を募集し*1、また新しくメンバーも入って最終的にはwriter 4人体制で進めることになりました。

とはいえ、原案もほぼない状態なので年内の開催は不可能でした。そこで、開催目標を2022年3月と定め、「3月までなら2021年度中なのでセーフ作戦」で行くことにしました。最終目標から逆算してスケジュールを作成し、それを守らせる役に徹しました。

ここで役割分担が自然に発生します。「コンテスト開催のノウハウを有しているが競プロ力はないBadlylucky」と「競プロ力はあるがコンテスト開催のノウハウがないkotamanegi」の2人をリーダーとし、問題のクオリティを見る部分をkotamanegiが担当し、進捗管理とコンテスト開催に伴う雑事の残り全てをBadlyluckyが担当する2大巨頭体制が出来上がりました。ソフトウェア開発の文脈だとリードエンジニアとプロダクトマネージャーの関係に近いかもしれません。

計画は2022年1月末まで原案を募集し、2月末までにgeneratorなどを整えてAOJに提出、3月で調整という流れに(当初)なっていました。私が入ったのが11月21日なので、かなりの突貫作業です。しかし若干の遅延を含みながらも、最終的にはほぼ予定通りに進行させることができました*2

急ぎの作業になるのでコンテストのクオリティが多少落ちることは最初から織り込み済みでした。コンテストを開催することが最大の目的なので、(可能な範囲で助言はするが)クオリティについてはあずかり知らぬという立場です。OUPC2021にいわゆる大ボス問が不在だったのはこのような事情によります。

ただ、集まったメンバーの中にはrimeを知らない人はもちろん、GitHubの使い方に精通していない人もいて、その対応のために(相対的に)一番詳しい自分が手本を示す必要がありました。そこで、当時原案で不足していた初心者向け問題*3を生やしつつGitHubやrimeの使い方のチュートリアルとなるようにしました。それがB問題のLongest Matchです。初心者向け問題として結構いい問題ができたので、出題することになりました。なので私は前回に引き続いて、今回もwriterとなりました。

しかし、kotamanegiは結局期間中に問題を作ることができませんでした。ボス問を作ろうと焦りすぎたのが良くなかったのかもしれませんが、私にはよく分からないです。writerとしては外れるものの、OUPC2021全体への貢献度は非常に高く実質writerと言って良いほどの働きをしたため、writerと同格扱いということになりました*4。役職名はCTO。AtCoderではABCでのりんごさんなどが近いかもしれません。

開催(前項のトピックは全て消化しているので、このセクションはほぼ余談です)

AOJでコンテストを開催することをお願いすると、本番のコンテストを用意する前にtester用の環境として、トライアルコンテストと呼ばれる予備的な非公開コンテストを準備してくれます。そこでtesterを募集するのですが、5月時点と比べてすごく集まりが悪く苦労しました。時間的猶予もなかったため、最終的にkotamanegiがE869120さんとsquare1001さんを外部から招聘することで解決しました。

また、自分のブログを持っていない人がいることが判明したので、解説を公開する手段を探したりしました。今回はGoogle Documentにしましたが、もっと良い方法はありそうです*5。また、kotamanegiがOUPC2021で仕事をしていたことを外部に伝えるために、解説の先頭にICPCを意識した全体講評を付けることや、講評に隠し文字を仕込むことを決定しました。

トライアルコンテストでの調整がやや難航したのと、開催日の有力候補だった3月27日が東京大学のUTPCに抑えられてしまったことから、コンテストは4月に開催することになりました。

clar対応が忙しいと予測されたので、Twitter担当をwriter以外から選出しました*6。Herring101がちょうどあぶれており今回は適任でした。

ただ蓋を開けてみると、よほど準備が良かったのかclarはわずか3件しか来ず、コンテスト中はTwitter係以外平和そのものでした。すまん。。。

知見

おじいちゃんなので昔話が長くてすみません

技術担当と進行係を完全に分離させることの効果

ここまで読むと、「ではなぜ当初のOUPC2021がうまくいかなかったのか」という話になってきますが、原因はいくつかあります。うまく文章にまとめることができないので、箇条書きで要点を列挙します。

  • リーダーが積極的に動いていないと動きづらい
    • 「自分が今何をすればいいのか」が分からないとメンバーは動けない
  • 締め切り駆動で厳しく動かしていかないと動かない(締め切り駆動)
  • ツールの使い方、ノウハウが分からない
    • 一人の作業なので、問題が生じた時に自力で解決しようというモチベーションになりにくい(放置してしまう)

一言で言うと、曖昧な作業割り当てをしてしまった、またその作業に責任がなかったため各人が停止したということになります。責任がないのはボランティアである以上仕方がないことですが、そうであるならば、モチベーションを保つためにリーダーはなおさら率先して動き、厳格な進捗管理を行い、適切なサポートを行う必要があります。これらは字面よりも負担の大きな作業です。kotamanegiはこれらのリーダーとしての作業と、作問のクオリティを担保する作業をまとめて行うつもりだったため、作業量と責任がリーダーひとりに集中することになりました。これは組織として健全ではありません。結果、kotamanegiが非常に多忙になってしまったこともあり、リーダーとしての進捗管理の作業が疎かになってプロジェクトは暗礁に乗り上げました。

再始動後は進捗管理を私が全て行い、kotamanegiは技術的な面に専念することができるようになりました。それにより責任が分散され、最初の計画時よりもプロジェクトのリスクが低い状態になりました。

2人の目標がはっきりしていたことも大きいと思います。私はコンテストの質には関心がなく、最初から(燃えてもいいので)開催することしか頭になかったので、進捗管理に徹することができました。

また、rimeの分かりやすいドキュメントが失われてしまったので、rimeのドキュメントの整備を行うなどのサポートも行いました。サポートでは、地味にめんどくさいmdファイルからhtmlファイルへの翻訳作業も行っています。「ここまでやれば後は何とかするから」という体制をうまく整えることができたのも、目標を定める上で効果的に働いたかもしれません。

ただ、私とkotamanegiが常に密な連携を取れていたというのが、このシステムの最大の成功要因である気もします。しかし、リーダーやマネジメントの作業は複雑なので、競プロの作問においても進捗管理を行う専門の人を用意するというのは有効な方策だと考えています。人間、そんなに思い通りに動かない。

f:id:A8pf:20220406185226p:plain
Sum of Coloring Problemなどに登場したブロックのデザインも担当しました。かなり頑張ったしとても良く出来たと思うのですが、誰も言及してくれなくてショック……

エンジニアの世界には「技術が優れている人が偉い」という風潮があると感じていますが、今回の件は「エンジニアリングの直接的な技術力と、人員配置や進捗管理を行うマネジメント力は同一ではない」という以前からの考えを補強するとともに、「技術が優れている人をマネジメントで消耗させてしまうのは痛手である」という考えになりました。もちろんだからと言って互いが互いをおろそかにして良いわけではありませんが。技術ももちろんやっていきたいが、技術のつよつよエキスパートになるというよりは、マネジメントの技術も磨く方向のフルスタックになりたいなぁと思うこの頃です。

作問リポジトリへのCI(自動テスト)の導入

OUPC2021では新しい試みとして、GitHub Actionsを使ったRimeの自動実行を導入しました*7。元々はRimeをインストールせずに作問を行うための環境整備のために行いましたが、実用的には本来のCIと同様の使われ方をしました。

ところが、GitHub Actionsを実行するマシンのスペックは非常に低く(特にCPU)、ローカルでの実行結果とCIの実行結果が食い違うということが多発しました。しかし、それでもGitHubのPRから問題の状態を確認できるのは計り知れない恩恵がありました。いちいち手元で rime test する必要がないのは大きい。

問題リポジトリが整っていれば簡単に導入することができるので、コンテストを企画している皆さまも導入されてはいかがでしょうか?

まとめ

本当は「僕はこういうことをしました! すごいでしょ!!!」とやりたかったけど、昔話が大好きなのでこういう形式になりました。とりあえず私のことは、崩壊寸前だったOUPC2021を、持ち前のマネージメント能力を使って開催まで持ち直した火消し人と覚えてくださるとBadlyluckyが喜びます。

謝辞

準備のためにお集まりくださったwriterとtesterとCTOとTwitter係の方々には、本当に感謝してもし切れないです。特にwriterの皆さまは、私みたいな競プロ水色で、全然やってなくて、RAINBOUでもゲームの話しかしない人に着いてきてくれてありがとうございました。

KowerKointはB1(!)でありながらエンジニアリングの全てに精通する人として、私とkotamanegiの補佐をするナンバー2としてよく働いてくれました。Yoikaは個性的でクオリティの高い問題を2問出してくれました。Doping Slayer、おそらく全問題で一番評価が高かったのではないでしょうか。vwxyzの行動にはたびたび驚かされましたが、kotamanegiの代わりにボス問を作ってくれてありがとうございました。また、作問作業ではかなり多くの知見や指摘をくださりとても助かりました。kotamanegiは……なかなか複雑な気持ちですが……まあ、このチャンスを与えてくれてありがとう。

後書き

記事中でも言及したRimeとGitHubについてのドキュメントは、近くいくつか追記してこのブログで公開予定です。

公開しました。

a8pfactory.hatenablog.com

a8pfactory.hatenablog.com

*1:tester希望の人もwriterとして扱う。というか原案も出揃ってないのにtesterを募るのはかなり悪手

*2:原案は10問集まり、そのうち9問を出したのでギリギリです。最終的に出題する問題数の2倍くらい原案があると安心です

*3:F問題Teaching Assistantは当初制約がO(N|report_i|)の中難易度問題でした。Python4倍ルールをこの時点で把握していればそのまま出せたかもしれません

*4:問題が燃えた時に責任を取らせる役割もあります。もちろんコンテストが燃えたら私が腹を切ります

*5:公開タイミングをきっちり管理する必要があるため、GitHub Pagesでは難しいと判断しました。このあたりは今後洗練されていくといいですね

*6:Twitter係は忙しくなるので新しく人を入れてでもwriterではない人がやるべきという考えです

*7:kotamenegiが勝手にやってくれました