ライトニングまさかり

その馬肉で和同開珎の刺繍をしよう

タイトル付け忘れたので今適当につけます

プロラボアドベントカレンダーほげ日目のほげです。アレの記事への張り付け方わかんないです。

 

自己紹介をすると、某IMAGINE THE FUTURE大学に進学した@kusohako です。@ichigo_o_re に書けよと脅されたので書きます。

 

記事に書く内容をtwitterで募集したところ、code festivalのショートコーディング大会である短縮王について書いてほしいといわれたので書きます。

 

ショートコーディングに詳しくない方のために説明しておくと、競技プログラミングの解答コードをできるだけ短くするという問題です。短縮王はAtcoder上で行われました。ページはこちらです。
http://code-festival-2015-shortcoding.contest.atcoder.jp/

 

私がcode festivalの事前公開問題に気づいたのは多分本選の2日前の夜くらいだったように思います。twitterを眺めていたら問題文が話題になっていました。キルミーベイベーは神。

 

A問題は1行目にデータの数nが与えられて、続くn行に1つづつ整数が与えられまして、2行目に与えられたデータ(つまりnの次の入力)がn個のデータの平均の半分以下だったら"Fail",そうでなければ"Pass"を出力する問題です。

 

事前に公開された問題はAnarchy Golfで公開されたんですが、入出力のフォーマットがすごいつらかったうえに本番では変更されるようなことを聞いたので、Atcoder上でコンテストが公開されるまでは本気を出す必要ないかな~とか考えていました。

 

本選会場で@orisano 君や@ichigo_o_re 君に挑発されたのでとりあえずその場で二人のスコアを抜きました。

 

短縮王の開始はcode festival本選の後だったので、本選でとても疲労しているコンディションで始めることになりました。

 

私がショートコーディングするときは、まず普通にAcceptするコードを書いて、それから短くしていくようなスタイルなので、この問題も例にもれず最初にコードを書きました。多分こんな感じでした。

n,s,f,a;
main(i){
scanf("%d",&n);
for(i=s=0;i<n;s+=a){
scanf("%d",&a);
f=i++?f:a;
}
n=!puts(n*f*2>s?"Pass":"Fail");
}

このコードの時点で空白や改行を削ると109byteですね

 

この段階で何やってるかわかんないしなんで動くのかもわかんないと思う人もいると思うので、C言語の仕様を簡単に箇条書きで説明しますと、
・scanf,printf,putsはstdio.hをインクルードしなくても使える
・変数や関数の宣言を省略するとint型と判断される
・x?a:bという演算子は,xがtrueの時aを,falseの時bを返します

 

さらに、AtcoderのCでは通常main関数は0を返さなければREになってしまうのですが、グローバル変数に非定数式で0を代入するとmainの戻り値が0になります。AtcoderC言語のputs()の戻り値は0でないです。

 

この辺の知識はまあ常識なのでわかる人はこの辺まで読み飛ばしてもいいと思います。コードは読めると思うので解説は省略します。

 

ここから、とりあえずfor文を削りたいなーと思ってmain再帰を使ってみたコードがこちらになります。

s,c,t;
main(n){
scanf("%d",c?&t:&n);
s+=~c--?t:-t*n*2-t;
t=n--?0*main(n):puts(s<0?"Pass":"Fail");
}

これで94byteですね

 

コードの解説をしようと思ったのですが思い出せない上に読むのが結構だるいので各自で勝手に読み取ってください。

 

このコードを提出した後は会場にいる人とご飯を食べたりゲームしたりしてました

ホテルに着いた後さあ本気出すぞと思いしているといつの間にか日付が変わっていて、喉が謎の痛みを訴えていました。風邪の初期症状です。

 

とりあえずA問題でC言語1位を取れたので寝ることにしました。そのコードがこちらです。

s,f;
main(n,t){
for(;~scanf("%d",n?&t:&f);)s=n--?s+t-2*f:0;
s=!puts(s<f?"Pass":"Fail");
}

85byteです。やっぱfor文使った方が短かったです。

 

2日目に起きると喉が痛くて体もだるかったです。完全に悪化しました。罪深い。

 

短縮王の評価方法を見ると、解いた問題数が多い方がいいらしいのでとりあえず問題を埋めてからコードを短縮することにしました。順位表を見るとわかる通り、A問題以外は完全にクッソ雑魚だったので風邪のせいにしたいです。

 

BはUnion Findするだけだったんですが、戻り値を省略しようとしたら戻してくれなかったりしたのでブチギレながらreturn文を書きました。

Cは全探索を適当に短くしました。

Dを普通に通すのがとてもだるかったです。だるすぎて短縮するのあきらめました。C++でゴリ押しました。

 

短縮王終了した後に解説が聞けたらしいんですけど、解説会場の告知がとてもわかりづらかったので行けませんでした。悲しい。

 

A問題C/C++部門で1位だったんですが、他の全ての部門1位は表彰されていたのに私だけ表彰されなかったのでとてもつらい思いをしました。

 

あとA問題の想定解は79byteでした。くやしい。