C言語によるショートコーディング(パスカルの三角形)第4回

| コメントをどうぞ

C言語によるショートコーディング(パスカルの三角形)第3回からの続きです。
前回のソース(その6修正後)は以下のとおりです。

v[20],i;
main(j){
    for(;i<20;i++)
        for(j=i;j>=0;j--)
            printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]);
}

その8.for文ではなるべく1回しか変数を使わない

以下の2つのfor文でiが3回とjが3回使われています。これを減らすことを考えます。

for(;i<20;i++)
for(j=i;j>=0;j--)

まず1行目ですが、単純にi++をi<20に持っていってi++<20とすると、ループ回数は変わらず20回ですが、処理ブロックにi=0~19だったのがi=1~20に変わってしまいます。
次に2行目ですが、j–をj>=0に持っていってj–>=0とすると、ループ回数は変わらずi+1回ですが、処理ブロックにj=i~0だったのがj=i-1~-1に変わってしまいます。
ということは、1行目と2行目を同時に修正すると、2行目のj=iの初期化はj=1~20と+1され、j>=0の条件はj>0(つまりそれはj)に変わり、j–を条件に持っていくと、処理ブロックはj=i~0と-1されつじつまが合います。この2行だけで31Bが26Bとなりました。

for(;i++<20;)
for(j=i;j--;)
v[20],i;
main(j){
    for(;i++<20;)
        for(j=i;j--;)
            printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]);
}

不要なブランクと改行を取り除くと88B(前回93B)となる。正しい結果となることを確認しておく。

v[20],i;main(j){for(;i++<20;)for(j=i;j--;)printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]);}

その9.for文一重化を検討する

for文一重化.c – ショートコーディング攻略wikiというテクニックがあるそうです。こんなこと自分では考えもしなかったですな。説明はリンク先を読んでください。

for(a;b;c)for(d;e;f)g;
for(a;e?g,f:(c,d,b););

機械的に当てはめていくと

v[20],i;main(j){for(;j--?printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]):(j=i,i++<20););}

結果がおかしい。i=0, j=1だから、いきなりj–の判定で変わってしまったのか。iとjを交換する。

v[20],j;main(i){for(;j--?printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]):(j=i,i++<20););}

今度は19行しか表示されない。仕方ないな、i++<20をi++<21にする。

v[20],j;main(i){for(;j--?printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]):(j=i,i++<21););}

できた!というわけで、ほとんど意味わからんけど86B(前回88B)となる。

その10.とにかく変数を使わない

(j=i,i++<21)部分、これって条件判定です。i<21はi-21と書けます。ならば(j=i++)-21と書けるんじゃね。

v[20],j;main(i){for(;j--?printf(j?"%d ":"%d\n",v[j]=!j?1:v[j]+v[j-1]):(j=i++)-21;);}

うごいた!というわけで、さらに意味わからんけど84B(前回86B)となる。

というわけで、その7まではギリギリありですが、特にその8は普段のコーディングではあり得ないですな。これ以上詰めるのは無理っぽいので、次は邪道編です。
つづく

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>