読者です 読者をやめる 読者になる 読者になる

ichirin2501's diary

いっちりーん。

AOJでShortCoding

先日告知してたAOJのコードです。

0001

http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/problem.jsp?vol=0&id=0001&tle=1&mle=32768&title=List%20of%20Top%203%20Hills&doc=4&lang=jp
このコードは一番目に上位3つのうちどれかの値が含んでたらだめなコード。でも通っちゃった☆
値を比較して変数に確保していく方法ではなく、qsortを利用しました。
qsortの比較関数はショートコーディング書籍で書かれてた手法です。先人達はすごいです。

// 124byte
s[];
M(int*a){return*1[&a]-*a;}
main(i){
  for(;~scanf("%d",s+i++);qsort(s,i,4,M));
  exit(!printf("%d\n%d\n%d\n",*s,s[1],s[2]));
}

出力を一度にするのではなく、1回に分けてループさせたほうが短くなった。

// 122byte
s[];
M(int*a){return*a-*1[&a];}
main(i){
  for(;~scanf("%d",s+i);i++);
  for(qsort(s,i,4,M);i-8;)printf("%d\n",s[--i]);
  exit(0);
}

まだまだ短く書けるようですが…どうやって書くんだろう。

0002

http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/problem.jsp?vol=0&id=0002&tle=1&mle=32768&title=Digit%20Number&doc=4&lang=jp
log10を使って桁数を求める。ぐーぐる先生で調べた結果がこれだよ!

// 69byte
main(a,b){
  for(;~scanf("%d%d",&a,&b);)
    printf("%d\n",a=log10(a+b)+1);
}

出力する桁数の値が1桁だと決め付ける、文字変換後、putsを利用すればさらに短く書けます。

// 63byte
main(a,b){
  for(;~scanf("%d%d",&a,&b);puts(&a))
    a=log10(a+b)+49;
}

たぶんこれが最短コードでしょう。cheatでない限り…。


0005

http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/problem.jsp?vol=0&id=0005&tle=1&mle=32768&title=GCD%20and%20LCM&doc=4&lang=jp
最初は再帰を利用したコードを書いたのですが、ループで求めたほうが短くなりました。

// 98byte
main(x,y,z,v,w)
{
  for(;~scanf("%d%d",&x,&y);printf("%d %d\n",v,x/v*y))
    for(v=x,w=y;w;w=z)z=v%w,v=w;
}

素直にgcdを求めるアルゴリズムを書いてますが、速度を犠牲にすればさらに短く出来るようです。


0006

http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/problem.jsp?vol=0&id=0006&tle=1&mle=32768&title=Reverse%20Sequence&doc=4&lang=jp
main再帰を利用しました。この問題の入力は 文字列[EOF] ではなく、文字列[改行][EOF] という入力なので、
改行が入力されたときに再帰が終わる処理をしています。
ここで少し脱線、main関数について。
main関数の第一引数にはコマンドオプションの個数(コマンド自体も含む)、
第二引数には各々へのポインタが格納されますが、オプションを何も指定しない場合は
第一引数には1、第二引数はゴミが格納されます。
main再帰ではこれらの初期値を条件分岐として利用出来ます。

// 71byte
main(i,s){
  i=getchar();return i-10&&main(i,0)+putchar(i)*s&&!puts("");
}

このコードを眺めていて、まだまだ短く出来るなぁ(無駄大杉)という感覚があったのですが
その感覚は当たっていたようで、さらに短くなりました。

// 57byte
main(i){
  return i-10&&main(getchar())&putchar(i-1?i:10);
}


ショートコーディングは楽しいけど、AOJでは控えようと思います。
今度はProjectEulerかなぁ。