472. Excess3

Active problemsが切れていたので久しぶりの出題。
簡単だけどちょっと考える問題…のつもりです。


結果はループ4回につき1回だけ読み込むという発想が出ずに惨敗。
10バイトも差があるんだから入出力の方法から見直すべきでした。


そういえばあなごるに出題するときの注意点はどこにも書いていないような気がするので僕が気にしていることをメモしておきます。

続きを読む

462. Power Set

お久しぶりです。もうちょっと頻繁に更新しよう・・・。

久しぶりにmain再帰を書いた気がします。入力がなくなったらgetchar()は-1を返すことを利用して再帰した後は0で左シフトしていきました。

ポイントとなったのは0を出力するタイミングで、関数から出るときに出力すると無駄な変数を使わなければならなくなります。関数に入った時に出力するようにするとかなり縮みました。

そういえば未だに謎なんですがffsって何の略なんだろう・・・?

Herbert Online Judge

友人がHerbert Online Judgeを構築したので紹介します。

http://herbert.tealang.info/

Herbert Online Judgeより

Herbertはwildnoodleによって開発されたゲームです。
Microsoft社による学生大会ImagineCupでは、3年間Algorithm部門の予選に用いられました。
その中で多くの熱狂的なプレイヤーが生まれましたが、現在では腕を競い合える場がありません。
このHerbert Online Judgeというサイトは、Herbertという楽しくて教育的価値も高いプログラミングゲームがこのまま忘れ去られてしまうのは余りにも勿体ない、Herbertを誰でもプレイできる場を提供したい、という思いのもと開発された非公式実装なのです

このブログの読者が分かりやすいようにいうとH言語でgolfするサイトです。
とてもわかりやすいルールで見た目以上に楽しいのでぜひ参加してみてください。

ショートコーディング攻略wiki始めました。

年始の目標に書いていたゴルフの解説サイト作りました!
http://w.livedoor.jp/short_coding/
本当はもう少し書いてからこのブログで宣伝しようと思ってたんですが、naiとnnさんに見つかったのでもう宣伝してしまいます。
試験期間中なのであまり書き足せないんですが、さ来週あたりからちゃんと書いていきます。
みんなで作ろうという趣旨のサイトなので参加者絶賛募集中です!

387. toggleCASE

アルゴリズム的にはbox paintと似てるなと思ったのでこれを元にして書きました。
最終的にみんな同じコードにたどり着いたのかと思いきや、全員違うという珍しいことが起きました。
注目すべきはnnさんが発見したmain再帰を使うと短くなるという点。
普通main再帰にすると

main(){for(;a;)b;}
main(){a&&main(b);}

のように1バイト伸びるんですが、今回は代入があったので、

main(x,y){for(;a;)x=b;}
main(x,y){a&&main(b);}

となって1バイト縮んでいます。なるほど・・・。
ということはbox paintも縮むということなのでbox paintの最短が更新されました。

368. permutation date

Permutationsを元にして書きました。
(さらに元をたどるとN Queensですが。)
deadline後、nnさんが113バイトまで縮めました。
ポイントは2つ。
・引数に0.を入れることで引数の数を3つから2つに削減
・d++<"\x09\x02\x09\x04\x09\x05\x09\x05\x09"[c]が再帰の終了条件にもなる
1つ目は僕の凡ミスですが2つ目は凄いですね・・・。

363. Squares Fixed

hosと競い合っているうちにぐんぐんコードが縮んでいきました。
最初は今の行と一行前の行の文字列をそれぞれ配列に持っていましたが、一つの配列をどんどん使っていくと上手く行きました。
(この方法を思いついた時、Brainfuckみたいだなーと思いました。)
98バイトごとにgets()していき、それをポインタ2つで見ていくという方法をとりました。
縮ませきれてない感じはありましたが、ほったらかしにしておいたらコード公開後にnnさんがすさまじい縮め方をしてきました。
特にputchar()の中はこんなにうまくいくのかーという感じです。


この問題を解いている時に気づいたのですが、

s[]={0,1};i,j;main(){printf("%d",s[i]+s[++i]);}

は2になるのに

s[]={0,1};i,j;main(){printf("%d",s[i]+s[j=++i]);}

は1になります。
前置インクリメントはいつも最初に評価されると思っていたのですがそうでもないみたいです。