2010-08-20 6 views
156

Dieser Code druckt die Karte von Indien. Wie funktioniert es?Wie generiert dieser Code die Karte von Indien?

#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; 
} 
+0

Screenshot der Ausgabe? –

+55

Es ist nur verschleiert C ... es gibt ganze Gesellschaften, die sich dieser Art von Wahnsinn verschrieben haben. – Mark

+11

Ausgabe: http: // Codepad.org/ngiITeZ4 –

Antwort

145

Die lange Zeichenfolge ist einfach eine in ASCII konvertierte Binärsequenz. Die erste for Anweisung macht b beginnen bei 10, und die [b+++21] nach der Zeichenfolge ergibt 31. Behandlung der Zeichenfolge als Array, Offset 31 ist der Beginn der "echten" Daten in der Zeichenfolge (die zweite Zeile in der Code-Probe Sie unter der Voraussetzung). Der Rest des Codes durchläuft einfach die Bitsequenz, wandelt die 1en und 0en in! 'S und Leerzeichen um und druckt ein Zeichen nach dem anderen.

Weniger Version verschleierten:

#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; 
} 

Die seltsame clevere Teil ist in den putchar Aussagen. Nehmen Sie die erste putchar. ASCII 'Z' ist 90 in Dezimal, also 90/9 = 10, was ein Newline-Zeichen ist. In der zweiten ist Dezimal 33 ASCII für '!'. Wenn Sie das niederwertige Bit von 33 umschalten, erhalten Sie 32, also ASCII für ein Leerzeichen. Dies führt dazu, dass ! gedruckt wird, wenn b ungerade ist, und eine Leerstelle gedruckt werden soll, wenn b gerade ist. Der Rest des Codes ist einfach da, um den "Zeiger" a durch die Zeichenfolge zu führen.

+20

Die Zeichenfolge ist keine Bitsequenz (beachten Sie, dass es im Code keine Bit-Shift-Operationen gibt). Es ist ein Lauflängencodierung des Bildes – interjay

85

Grundsätzlich ist die Zeichenfolge eine run-length encoding des Bildes: Alternierende Zeichen in der Zeichenfolge sagen, wie oft ein Leerzeichen und wie oft ein Ausrufezeichen hintereinander gezeichnet werden soll. Hier ist eine Analyse der verschiedenen Elemente dieses Programms:

Die codierte Zeichenkette

Die ersten 31 Zeichen der Zeichenfolge ignoriert werden. Der Rest enthält Anweisungen zum Zeichnen des Bildes. Die einzelnen Zeichen legen fest, wie viele Leerzeichen oder Ausrufezeichen nacheinander gezeichnet werden.

Outer for-Schleife

Diese Schleife geht über die Zeichen in der Zeichenfolge. Jede Iteration erhöht den Wert b um eins und weist das nächste Zeichen in der Zeichenfolge a zu.

Inner for-Schleife

Diese Schleife zieht einzelne Zeichen, und ein Zeilenumbruch, wenn es erreicht das Ende der Zeile. Die Anzahl der Zeichen ist a - 64. Der Wert c geht von 10 bis 90 und wird auf 10 zurückgesetzt, wenn das Zeilenende erreicht ist.

Die putchar

Dies kann neu geschrieben werden als:

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

Es das entsprechende Zeichen zieht, je nachdem, ob b gerade oder ungerade ist, oder ein Zeilenumbruch, wenn nötig.

+1

Warum werden die ersten 31 Zeichen ignoriert? –

+3

@PankajMahato, weil "b" bei 10 beginnt und der Index "(b ++) + 21" ist, was bei 31 beginnt. – interjay