コードを短くするのって楽しいですよね?(5)

コードは如何にして縮められたのか。ここで紹介するのは非正攻法による解法。


要するに、acceptされれば何でもokという条件下で挑戦してみた。
ただし、これをやってしまうと、本来の課題とはかけ離れてしまうため、一気に楽しくなくなる。それでもコードを縮めることは容易ではなくて、私には67byteまでしか縮められなかった。(id:tanakh:20051128#p1さんは65byte)


ひとつのInput(一連の入力データ)に対していくつのテストケースが存在するのかを調べるところから始めた。puts(r?"yes":"no");の部分にトラップを仕込む。


たとえば、トラップは以下のようにする。


puts(r?"yes":"no");
if (++c == 20) return;

こうすれば、20回目のテストケースの結果を出力してmain関数から抜け、21個目のテストケースに対する出力は行なわない。つまり、テストケースが21以上あれば“acceptされない”。


このように、acceptされるか、されないのか、という1bitの情報を手がかりにテストケースの数を特定する。20ではaccept。10ではWA(wrong answer)。15でもWA。17はaccept。16はWA。よって、テストケースは17であることが判明。


ただし、論理的に言えば、Inputが複数あった場合、その最長のテストケースが17であることを意味しているに過ぎない。すべてのInputでテストケースで17あるとは限らない。


次に、17番目のテストケースから、Yes/Noを確定させていく。


puts(r?"yes":"no");
if (++c == 16) { puts("yes"); return; }

accept。よって17番目はY。


puts(r?"yes":"no");
if (++c == 15) { puts("yes"); puts("yes"); return; }

NA。よって、16番目はN。


puts(r?"yes":"no");
if (++c == 14) { puts("yes"); puts("no"); puts("yes"); return; }

accept。よって15番目はY。以下、これを繰り返して、answerを確定させていく。
ところが、2,3,4番目は確定しない。これは、2種類以上のInputがあることを意味する。そこで、2,3,4番目をとばして、1番目のanswerを判定。


if (++c==1) puts("yes") else puts(r?"yes":"no");

これがaccept。よって1番目はY。


以上で、17のテストケースに対する答えはy???nnyyyyynyyynyと確定。


ここまでは、たにぐちさんの手法と同じはず。


それにしても、これ以降の複数ファイルの解析は(オンラインジャッジの)
外からは面倒です。


果たしてそうかな?(つづく)