2010-08-20 10 views
156

Questo codice stampa la mappa dell'India. Come funziona?In che modo questo codice genera la mappa dell'India?

#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 dell'output? –

+55

È semplicemente offuscato C ... ci sono intere società dedicate a questo tipo di follia. – Mark

+11

Uscita: http: // codepad.org/ngiITeZ4 –

risposta

145

La stringa lunga è semplicemente una sequenza binaria convertita in ASCII. La prima istruzione for fa partire b a 10 e [b+++21] dopo che la stringa restituisce 31. Trattando la stringa come una matrice, l'offset 31 è l'inizio dei dati "reali" nella stringa (la seconda riga nell'esempio di codice che si fornito). Il resto del codice scorre semplicemente attraverso la sequenza di bit, convertendo gli 1 e gli 0 in! E gli spazi bianchi e stampando un carattere alla volta.

Meno offuscato versione:

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

La strana parte intelligente è nelle putchar dichiarazioni. Prendi il primo putchar. ASCII 'Z' è 90 in decimale, quindi 90/9 = 10 che è un carattere di nuova riga. Nel secondo, il decimale 33 è ASCII per '!'. La commutazione del bit di ordine basso di 33 fornisce 32, che è ASCII per uno spazio. Ciò causa che ! si stampi se b è dispari e se uno spazio vuoto si stampa se b è pari. Il resto del codice è semplicemente lì per percorrere il "puntatore" a attraverso la stringa.

+20

La stringa non è una sequenza di bit (si noti che non ci sono operazioni di spostamento di bit nel codice). codifica dell'immagine a lunghezza d'esecuzione – interjay

85

Fondamentalmente, la stringa è un run-length encoding dell'immagine: caratteri alternati nella stringa indicano quante volte è possibile disegnare uno spazio e quante volte è necessario disegnare un punto esclamativo consecutivo. Ecco un'analisi dei vari elementi di questo programma:

La stringa codificata

I primi 31 caratteri di questa stringa vengono ignorati. Il resto contiene istruzioni per disegnare l'immagine. I singoli caratteri determinano quanti spazi o punti esclamativi disegnare consecutivamente.

esterno per il ciclo

Questo ciclo va oltre i caratteri della stringa. Ogni iterazione aumenta il valore di b di uno e assegna il successivo carattere nella stringa a a.

interno per ciclo

Questo ciclo patte singoli caratteri, e una nuova riga quando raggiunge la fine della linea. Il numero di caratteri estratti è a - 64. Il valore di c passa da 10 a 90 e si reimposta su 10 quando viene raggiunta la fine della riga.

Il putchar

Questo può essere riscritto come:

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

Essa trae il carattere appropriato, a seconda che b è pari o dispari, o un ritorno a capo quando necessario.

+1

Perché i primi 31 caratteri vengono ignorati? –

+3

@PankajMahato perché 'b' inizia a 10 e l'indice è' (b ++) + 21', che inizia a 31. – interjay

Problemi correlati