コード圧縮・その後
なんだか思ったよりも多くの人がチャレンジしてくださったようでうれしいです。
私は完全においていかれてしまいました。
最初に書いた208バイトのコードはこんなのでした。
#include<iostream> using namespace std; int p(int u){ char c; int v,l; return cin>>c>>c,c-')'?cin.unget(),cin>>v,u-=v,l=p(u),v=p(u),cin>>c,l>0||v>0||l*v&&!u:-1; } main(){ for(int n;cin>>n;puts(p(n)>0?"yes":"no")); }
うわあ、これは短くなった。
って、思ったんですよ。ほんとですよ。
それからCであっさりと120バイト台が達成されることになる。
私のもてるCの知識をすべてつぎ込んで作った121バイトのソースが
r,v; p(u){scanf(" (%d",&v)?p(v=u-=v),p(u),v=r&=!!v:0;scanf(" )");} main(){for(;r=scanf("%d",&v)>0;puts(r?"no":"yes"))p(v);}
これ。
リーフを検出する方法がよく思いついたなぁ、
というか、これ見てもどう動くのかすぐには分からんでしょ?
でも、これもすぐに数バイト抜かれることに。
上のコードは二日間考えても一バイトも縮まなかったので、
おそらく間違っていても通るアルゴリズムと言うのが関係していると思う、
というか、思いたい。
それから、しばらくして100バイト台の出現。
これは明らかに違うタイプのコードだろうなぁ、と思っていましたが、
スタックを用いたアルゴリズムのようで。
私はまさかスタックを用いた実装の方が短くなるとは思ってもいませんでした。
上のコードではscanf()が三つあって、これを減らさねば短くなりようが無い。
というわけで、これまたいろいろ考えて、
r,v,b; p(u){ scanf("%d (",&v)>0?b++?v=!(u-=v),p(u),p(u),v=r|=v:p(v):0; scanf(" ) ("); } main(){for(;p(b=r=0),b;puts(r?"yes":"no"));}
二つで何とかする実装はできた。
でも今度はグローバル変数が増えて、コードサイズは前よりも大きくなってしまいました。
それから…。
http://www.taniguchitomoya.com/diary/?date=20051125#p01
こちらの解析により、入力が大体判明。
て、これ、
http://www.inf.bme.hu/contests/tasks/
ここの入力まんまかな。
で、それを利用して、通すことが可能らしい。
ので、私も便乗して通してみる。
一応ひとつ新機軸は盛り込んだ…つもり。
でも、まぁ、やっぱり、あんまりうれしくは無いかも…。
うーん、しかし、なんだか疲れた。
これはもういいかな。