このコードはどのようにしてインドの地図を生成しますか?


169

このコードは、インドの地図を印刷します。それはどのように機能しますか?

#include <stdio.h>
main()
{
    int a,b,c;
    int count = 1;
    for (b=c=10;a="- FIGURE?, UMKC,XYZHello Folks,\
    TFy!QJu ROo TNn(ROo)SLq SLq ULo+\
    UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^\
    NBELPeHBFHT}TnALVlBLOFAkHFOuFETp\
    HCStHAUFAgcEAelclcn^r^r\\tZvYxXy\
    T|S~Pn SPm SOn TNn ULo0ULo#ULo-W\
    Hq!WFs XDt!" [b+++21]; )
    for(; a-- > 64 ; )
    putchar ( ++c=='Z' ? c = c/ 9:33^b&1);
    return 0;
}

63
それはCを難読化しただけです...この種の狂気に専念している社会全体があります。
マーク


2
#include "Stdio.h":すべてのコンパイラで機能しますか?ミスキャップのある作業コードを入手できることを知って驚いています。多分それはWindows(大文字と小文字を区別しないFS)で
代わりに

2
そのようなもっと楽しいコードについては、[The International Obfuscated C Code Contest] [ ioccc.org/]を参照してください。
DarkDust 2010

12
初心者レベルからCを学ぶ限り、コードを理解するのは意図的に難しく、理解することから得られることは多くないことに注意してください。
タイラーマクヘンリー

回答:


154

長い文字列は、単にASCIIに変換されたバイナリシーケンスです。最初のforステートメントはb10から始まり[b+++21]、文字列は31になります。文字列を配列として扱う場合、オフセット31は文字列内の「実際の」データの始まりです(コードサンプルの2行目)。コードの残りの部分は単にビットシーケンスをループし、1と0を!と空白に変換して、一度に1文字ずつ出力します。

難読化されていないバージョン:

#include "stdio.h"
int main (void) {
    int a=10, b=0, c=10;
    char* bits ="TFy!QJu ROo TNn(ROo)SLq SLq ULo+UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^NBELPeHBFHT}TnALVlBLOFAkHFOuFETpHCStHAUFAgcEAelclcn^r^r\\tZvYxXyT|S~Pn SPm SOn TNn ULo0ULo#ULo-WHq!WFs XDt!";
    a = bits[b];
    while (a != 0) {
        a = bits[b];
        b++;
        while (a > 64) {
            a--;
            if (++c == 'Z') {
                c /= 9;
                putchar(c);
            } else {
                putchar(33 ^ (b & 0x01));
            }
        }
    }
    return 0;
}

奇妙な巧妙な部分はであるputchar文。最初を取るputchar。ASCII 'Z'は10進数で90なので、90/9 = 10は改行文字です。2番目では、10進数の33はのASCIIです'!'。33の下位ビットを切り替えると、32になります。これは、スペースのASCIIです。これにより!b奇数の場合は印刷され、偶数の場合は空白スペースが印刷されbます。コードの残りの部分は、単に「ポインタ」aを文字列内でウォークするためにあります。


22
文字列はビットシーケンスではありません(コードにはビットシフト演算がないことに注意してください)。これは、画像のランレングスエンコーディングです。
インタージェイ2010

89

基本的に、文字列は画像のランレングスエンコーディングです。文字列内の交互の文字は、スペースを描画する回数と、感嘆符を連続して描画する回数を示します。このプログラムのさまざまな要素の分析を次に示します。

エンコードされた文字列

この文字列の最初の31文字は無視されます。残りは画像を描くための指示を含みます。個々の文字によって、連続して描画するスペースまたは感嘆符の数が決まります。

ループの外側

このループは、文字列内の文字を調べます。反復ごとにの値がb1ずつ増加し、文字列の次の文字がに​​割り当てられaます。

ループの内側

このループは、個々の文字を描画し、行末に達すると改行します。描かれた文字数はa - 64です。の値はc10から90になり、行の終わりに達すると10にリセットされます。

putchar

これは次のように書き換えることができます。

++c;
if (c==90) {       //'Z' == 90
    c = 10;        //Note: 10 == '\n'
    putchar('\n');
}
else {
    if (b % 2 == 0)
        putchar('!');
    else
        putchar(' ');
}

b偶数か奇数かに応じて適切な文字を描画するか、必要に応じて改行します。


1
最初の31文字が無視されるのはなぜですか?
Pankaj Mahato 14年

3
ため@PankajMahato b10で開始し、指数が(b++)+2131で開始する、
interjay
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.