ICPC 国内予選 2017

今年もICPC国内予選に参加していました.
ブログには2014年の以外一切書いてませんでしたが一応ずっとnocowで出ていて,2013と合わせるとnocowのメンバーは全員5回目ということで最後の参加になります.

詳しいことはosrehunが書いてくれたのですが, osrehun.hatenadiary.jp 一応最後なので参加記を残しておきます.

メンバーは3年前から同じ

  • hec (@osrehun)
  • nokoTaro (@xthexworldx)
  • icchy (@icchyr)

で,上2人がコーダー,僕は環境構築担当です.

~15:00

練習セッションの存在を完全に忘れていて,僕だけリモート参加

f:id:icchyr:20170715094635p:plain

L問題が残っていたので先にそっちだけやった

M問題は例年通りだと,1回目は何回か試せば通って2回目でほぼ確実に落ちるようになっていたと記憶しているが,今年は1回目が100ケースくらいあって,そもそも手動だとキツイみたいな感じだった.
あと順位表をみると数十回WAしてACしたチームとかがちらほらいたので,Data1が通せればそのままData2も通せるんじゃないかと思った.適当に100通り全探索するスクリプトを書こうと思ったけど,これはCTFではないしサーバーに負荷をかけるのが躊躇われたのでやめた.

15:00~16:00

会場入りして,諸々の準備をした.
チームで使う環境を一新したのでプリンタの設定に手こずった.プリンタの型番と同じドライバが存在しなかったが,適当に似た番号にしたら行けるということをhecが覚えていたのでプリンタ設定AC.

16:00~16:30

僕が急に「やっぱり印刷投げるのいい感じに自動化したい」と言い出す(は?)

  • lprコマンドでhtmlを印刷 → キレイなhtmlソースが出てくる(それはそう)
  • Javascriptwindow.printで印刷ダイアログを自動で出していく(別チームのメンバーが考案) → クリックが面倒なのでダメ

結局htmlを印刷するにはWebブラウザによるレンダリングが必要なので,ブラウザ無しではできない
→ Headless Chrome使えばいいんじゃね?

Chromeにはバージョン59からヘッドレスモードというのが加わって,これがPhatomJSにトドメを刺した.
ざっくり言うとGUIのウィンドウを作らずにブラウザを立ち上げる機能で,パフォーマンス良くブラウジングを自動化できる.最近ではGoogle CTFのXSS問題とかで使われたりした.

コマンドで書くと

~$ google-chrome --headless --disable-gpu [OPTIONS] [URL]

が基本で,簡単な操作についてはそもそもオプションで使えたりする.

developers.google.com

今回は--print-to-pdfを使ってPDFを生成し,それを印刷する感じにした.

ちなみにICPCの国内予選は提出したり順位表を見るのにはログインが必要だが,問題を見ること自体は認証無しで可能(これは練習セッションで確認済み)だった. このおかげでログイン処理を書く必要が無く,URLをそのまま直に叩けば問題ページが降ってきた.

~$ for d in {A..H}
> do
> google-chrome --headless --disable-gpu --print-to-pdf http://********/${d}_ja.html
> lpr output.pdf
> done

という感じにするとA~H問題までの問題が印刷される.今回はうちの大学から3チーム出ていたので,lpr output.pdfだけfor文で回した.

↑のコマンドを書いてメモったのが開始5分前で,提案しつつ「事故っても責任は持てないよ」と逃げ道を作っておく.🚩

16:30~17:00

競技開始.
まず問題文を印刷するコマンドを打つ.

プリンタの側で待機している問題文配布担当から出されるNG🙅.

Not Found

The requested URL /********/_ja.html was not found on this server.


Apache/2.4.7 (Ubuntu) Server at icpc.yamagula.ic.i.u-tokyo.ac.jp Port 80

こうして僕たちの最後のICPCは幕を閉じた.
(完)






















フラグ🚩回収に成功したとこで気を取り直して再度コマンドを打つ.今度は大丈夫そう.

僕がやらかしてる間にhecがターミナルの後ろにあるブラウザの画面からA問題を読み取っていて,とりあえずテンプレート等を打ってすぐ交代する.

ちょっとデバッグに手こずって開始10分後くらいでAC.大学内で一番遅かったらしい.
nokoTaroがBを詰め終わっていたのでコーディング交代.hecがCを読み終わって解法を詰めているところなので僕はDを読む.
一瞬で読み終わったのでEをちら見する.これも一瞬で読み終わる.
hecにDの概要を伝えたらO(1)で解法が降ってきた.Bのサンプルが合わなくて紙デバッグに移る.同時にhecがCの実装を開始.

Bのデバッグがすぐ終わったのでCをコーディングしてる途中で交代して修正してAC.
そのあとhecがCを通してそのままDの実装に移る.この時点で30分くらいだったと思う.

17:00~17:30

Eが読み終わってるので僕はFを読む.これも一瞬で読み終わるが,頭が弱いので折りたたみの様子を完全にイメージできず,メモ用の紙を使って小道具を作った.

これが後に大きく活躍したらしい.

nokoTaroがGの方針が思い浮かばないとのことなので,一旦Fを一緒に考えてもらう.
途中でDのデバッグ作業に呼ばれてsegvの箇所を特定するなどした.間もなくしてDが通る.

17:30~18:00

Eの概要をhecに伝えたがちょっと方針に確信が持てないのでFを手伝ってもらう.
3人でウンウン唸った後hecがよくわからない方法で通してた.

18:00~19:00

hecと適当に相談して,制約を見るとどうやらevaluatorを作ってぶん回せば行けそう(雑)ということがわかったのでそのままコーディングしてもらう.
nokoTaroがやはりGの方針が浮かばないとのことなので問題を見る.探索する近傍に優先順位をつけて反時計周りに辿れば良さそうということに気づくが,G問題ということもあり流石にそれはないでしょwみたいなやり取りを数回繰り返す.
途中でHを見て,幾何だけどなんとなく行けそうな匂いがしてしまう.しかし過去の経験上,幾何に手を付けて時間を溶かしてオワリみたいな展開が幾度となくあったのでGに戻る.
やはり先ほどの解法で反例が見つからないので強く主張する.悩んだ結果とりあえずコーディングだけしてみよう,ということに.
Eのバグ取りに手こずっていたようなので,一旦交代してnokoTaroにコーディングしてもらう.適当にバグを取ってサンプルも通ったのでsubmitする.WA.
Eの実装に戻ってもらいつつ,Gのテストケースを軽く印刷してもらう.18:30くらいに反例が見つかった.ここで右手法を使えば良いということに気づいて,nokoTaroに解法を伝える.

Eのバグが取れてサンプルも通ったとのことなので,Data1を処理している間にGのコーディングをしてもらう.いくつかバグを踏みつつ,EのData1の処理が終わったので提出.Correctで盛り上がる.
そのままGのコーディングを続けてもらい,バグが取れたところでEのData2の処理が終わる.提出してAC.6完で勝ちを確信する.

19:00~19:30

まあ解法雑だし最悪通らなくてもいいや…という気持ちでGを投げてもらう.AC.7完でかなり盛り上がる.

順位表を確認すると東大に挟まれていて笑う.その時点では4位だったのでshuriken通してくれ〜みたいな謎の祈りをしながら一応Hを見る.
完全に解法は詰めきれていなかったが,とりあえず幾何ライブラリを写経していた.
Hを考える気力が残っていなかったのであとは適当に順位表を眺めていたら,shurikenがGを通して4位になったので√29を確信する.

競技終了.7完5位という過去最高の結果だった.hecは神.僕はカス.

その後は会場の撤収作業を済ませ,適当に酒を飲むなどした.

おわりに

今回はそこそこ役に立てたので良かった.

Headless Chromeを使うと問題文印刷がかなり楽になるので来年度以降是非活用して下さい.typoをすると404 Not Foundなページが30枚近く出てくることになるので気をつけましょう.