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

| コメントをどうぞ

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

int v[20][20];
int main(){
    int i,j;
    for(i=0;i<20;i++){
        for(j=0;j<=i;j++){
            if(j==0)
                v[i][j]=1;
            else
                v[i][j]=v[i-1][j-1]+v[i-1][j];
            printf("%d ",v[i][j]);
        }
        printf("\n");
    }
}

その1.int型とか言わなくても、gccではint型。さらにグローバル変数は0で初期化される。main()の第1引数はint型。ただしローカル変数の値は不定。

ということで、int v、int mainの”int “(4B)は不要、int i;をグローバル変数にすれば4B減り、”i=0″(3B)も不要。”int j;”はmain(j)とすると5B減る。しかし、今回は毎回j=0の代入が必要。通常はmain(j)はj==1となる。

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

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

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

その2.if-elseは3項演算子に置き換える。

if(j==0)y=a;else y=b;は、y=(j==0)?a:b;のように書き換えます。ここで、”(j==0)?”は”!j?”(3B)で十分です。

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

不要なブランクと改行を取り除くと126B(前回144B)となる。正しい結果となることを確認しておく。この時点でブランクはprintfの”%d “だけとなる。

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

その3.1つの変数を代入と参照する。

“v[i][j]”は長いので、printfの中で代入して、その結果を参照するようにする。これにより、内側のjのfor文のブレス{}が不要となる。

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

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

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

その4.まだ3項演算子が使える

printfが2回も使うのがイヤなので、改行出力を考慮する。ループを抜ける条件はj==iの時であることが分かるので、printf(j==i?”%d\n”:”%d “のように行末の値はブランクを出力しなくする。なお、j==iと比較するより、i-j?”%d “:”%d\n”のようにj!=iを比較した方が1B減る。これにより外側のiのfor文のブレス{}が不要となる。

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

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

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

前回の160Bから112Bまで詰めてきました。ブランクや改行のないソースを見てもまだ理解できそうです。でも100Bは切りたいですね。
つづく

コメントを残す

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

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