web-dev-qa-db-fra.com

Comment ce code génère-t-il la carte de l'Inde?

Ce code imprime la carte de l'Inde. Comment ça marche?

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

La longue chaîne est simplement une séquence binaire convertie en ASCII. La première instruction for fait que b commence à 10, et le [b+++21] après que la chaîne ait rendu 31. Traitant la chaîne comme un tableau, le décalage 31 est le début des données "réelles" de la chaîne (la deuxième ligne de l'exemple de code fourni). Le reste du code parcourt simplement la séquence de bits, convertissant les 1 et les 0 en! Et en espaces et en imprimant un caractère à la fois.

Version moins masquée:

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

Le étrange la partie intelligente est dans les déclarations putchar. Prenez le premier putchar. ASCII 'Z' est égal à 90 en décimal, donc 90/9 = 10, qui est un caractère de nouvelle ligne. Dans le second, le nombre décimal 33 est ASCII pour '!'. En basculant le bit de poids faible de 33, vous obtenez 32, ce qui correspond à ASCII pour un espace. Cela provoque ! à imprimer si b est impair, et un espace vierge à imprimer si b est pair. Le reste du code est simplement là pour guider le "pointeur" a à travers la chaîne.

154
bta

Fondamentalement, la chaîne est un codage de longueur de l'image: les caractères alternés de la chaîne indiquent le nombre de fois qu'un espace doit être dessiné et le nombre de fois où un point d'exclamation doit être tracé. Voici une analyse des différents éléments de ce programme:

La chaîne codée

Les 31 premiers caractères de cette chaîne sont ignorés. Le reste contient des instructions pour dessiner l'image. Les caractères individuels déterminent le nombre d'espaces ou de points d'exclamation à dessiner consécutivement.

externe pour la boucle

Cette boucle parcourt les caractères de la chaîne. Chaque itération augmente la valeur de b de un et attribue le caractère suivant de la chaîne à a.

Inner for loop

Cette boucle dessine des caractères individuels et une nouvelle ligne chaque fois qu'elle atteint la fin de la ligne. Le nombre de caractères dessinés est a - 64. La valeur de c va de 10 à 90 et est réinitialisée à 10 lorsque la fin de la ligne est atteinte.

Le putchar

Cela peut être réécrit comme:

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

Il dessine le caractère approprié, selon que b est pair ou impair, ou une nouvelle ligne si nécessaire.

89
interjay