トリッキーコードネット トップへ戻る   C/C++, Java, Perl, PHP, JavaScript, アルゴリズム, ショートコーディング, IOCCCコードの解説, 等々

サイト情報

トリッキーなコード

7行プログラミング

物凄いコード集

アルゴリズム

データ構造

C/C++な話題

コードサンプル

ツール/環境構築

開発ノウハウ 等

ネタ/ジョーク集

おススメ書籍/サイト

サイトTOP >> 物凄いコード集 >> 数字の渦巻きを表示 (C言語)

数字の渦巻き表示 (C言語 - IOCCC)

a[900];        b;c;d=1        ;e=1;f;        g;h;O;        main(k,
l)char*        *l;{g=         atoi(*         ++l);         for(k=
0;k*k<         g;b=k          ++>>1)         ;for(h=       0;h*h<=
g;++h);        --h;c=(        (h+=g>h        *(h+1))       -1)>>1;
while(d        <=g){          ++O;for        (f=0;f<       O&&d<=g
;++f)a[        b<<5|c]        =d++,b+=       e;for(        f=0;f<O
&&d<=g;        ++f)a[b        <<5|c]=        d++,c+=       e;e= -e
;}for(c        =0;c<h;        ++c){          for(b=0       ;b<k;++
b){if(b        <k/2)a[        b<<5|c]        ^=a[(k        -(b+1))
<<5|c]^=       a[b<<5         |c]^=a[        (k-(b+1       ))<<5|c]
;printf(       a[b<<5|c       ]?"%-4d"       :"    "       ,a[b<<5
|c]);}         putchar(       '\n');}}       /*Mike        Laman*/
↑のコードは、1984年(第一回)IOCCCの登場作品です。 このコードをコンパイルして実行すると、数字の渦巻きが表示されます。( ^ω^)オモスレー 数字の渦巻きって何ぞや??と思われた方、↓の画像をご覧下さい。 渦巻き数字プログラム 実行結果 中央に1があり、そこから反時計回りに任意の数まで、数字が順に並んで表示されます。 C言語の標準出力は、 左 → 右 そして、 上 ↓ 下 へと表示されるため、最終的に渦巻き状に数字を配置するには、出力の都度、計算が必要になります。 ちょっと面白いです^^;) VC++2005での実行方法: 特にコードを修正する必要もなく、そのままコンパイル、実行できます。 ただし、以下の様な警告が表示されるため、 ---------------------------------------------------------------- warning C4013: 関数 'atoi' は定義されていません。int 型の値を返す外部関数と見なします。 warning C4013: 関数 'printf' は定義されていません。int 型の値を返す外部関数と見なします。 warning C4013: 関数 'putchar' は定義されていません。int 型の値を返す外部関数と見なします。 ---------------------------------------------------------------- これが気になる方は、コードの先頭に以下2行を記述して下さい。
#include <stdio.h>
#include <stdlib.h>
出来上がった実行ファイルに、パラメータ(幾つの数までの渦巻きを表示するか)を渡せば、 数字の渦巻きが表示されます。 それではいよいよ、お待ちかね、アルゴリズムの解説を行います。キタ━(゚∀゚)━!!!!! 冒頭のコードですが、そのままだと非常に見辛い!! ・・・というわけで、まず改行 及び インデントを入れます。 そして、変数O(オー)が、0(ゼロ)と紛らわしい為「r」に置換します。 変数l(エル)が、1(イチ)や|(or演算子)と紛らわしい為、「s」に置換します。 ついでに、お行儀良く#include<stdio.h>と、#include<stdlib.h>も付け足します。 という訳で、冒頭のコードを多少読みやすく(?)修正したコードがコチラ↓↓
#include <stdio.h>
#include <stdlib.h>

a[900];
b;
c;
d=1;
e=1;
f;
g;
h;
r;

main(k,s)char**s;
{
    g = atoi(*++s);

    for(k=0; k*k < g; b=k++>>1);
    for(h=0; h*h<=g; ++h);

    --h;
    c = ( (h += g>h*(h+1)) -1 ) >> 1;

    while(d <=g){
        ++r;
        for(f=0; f< r && d<=g; ++f)
            a[b<<5|c] =d++, b+=e;
        for(f=0; f<r && d<=g; ++f)
            a[b<<5|c]=d++, c+=e;
        e= -e;
    }

    for(c=0; c<h; ++c){
        for(b=0; b<k; ++b) {
            if(b <k/2)
                a[b<<5|c] ^=a[(k-(b+1)) << 5|c] ^= a[b<<5|c] ^= a[(k-(b+1))<<5|c];

            printf(a[b<<5|c] ? "%-4d" : "    ",a[b<<5|c]);
        }
        putchar('\n');
    }
}
/* Mike Laman */
このコードの先頭から読み解いていきます。 C言語では、変数の型が宣言されない場合、int型変数とみなします。 その為、グローバル変数のa,b,c,d,e,f,g,h,rは int型の変数です。 main関数のパラメータkも、int型の変数です。 また、main(k,s)char**s;{} は古いコードの書き方ですが、現在でいう main(k, char ** s){} に相当します。 (つまり、main(k,s)char**s;{} の部分は、変数名の違いこそあれ、良く目にする main(int argc, char ** argv){} と同じ物だという事です^^;) その下の g = atoi(*++s) ですが、 プログラム実行直後、 *sには第1パラメータ(通常はプログラムのパス)文字列へのポインタ、 *(s+1)には第2パラメータ(ここでは、ユーザが入力した任意の数)文字列へのポインタ が格納されています。 つまり、g = atoi(*++s)は、g = atoi( *(s+1) )と直す事ができ、変数gにユーザが入力した値を代入しているだけです。
         このエントリーをはてなブックマークに追加   


作業効率化・ライフハックのオススメ記事




コンピュータ・テクノロジーのオススメ記事





恋愛・人間関係のオススメ記事




※ 当サイトは、トップページからリンクで辿る事の出来るページに限り、リンクフリーです。
※ 当サイトの閲覧/利用によって生じた如何なる損害も、当サイト管理人は責任を負いません。
※ 当サイトの内容を転載される場合は、当サイトへのリンクをお願い致します。