This code prints the map of India. How does it work?
#include
main()
{
int a,b,c;
int count = 1;
for (b=c=10;a=\"- FIGURE?, UMKC,XYZH
Basically, the string is a run-length encoding of the image: Alternating characters in the string say how many times to draw a space, and how many times to draw an exclamation mark consecutively. Here is an analysis of the different elements of this program:
The encoded string
The first 31 characters of this string are ignored. The rest contain instructions for drawing the image. The individual characters determine how many spaces or exclamation marks to draw consecutively.
Outer for loop
This loop goes over the characters in the string. Each iteration increases the value of b
by one, and assigns the next character in the string to a
.
Inner for loop
This loop draws individual characters, and a newline whenever it reaches the end of line. The number of characters drawn is a - 64
. The value of c
goes from 10 to 90, and resets to 10 when the end of line is reached.
The putchar
This can be rewritten as:
++c;
if (c==90) { //'Z' == 90
c = 10; //Note: 10 == '\n'
putchar('\n');
}
else {
if (b % 2 == 0)
putchar('!');
else
putchar(' ');
}
It draws the appropriate character, depending on whether b
is even or odd, or a newline when needed.
The long string is simply a binary sequence converted to ASCII. The first for
statement makes b
start out at 10, and the [b+++21]
after the string yields 31. Treating the string as an array, offset 31 is the start of the "real" data in the string (the second line in the code sample you provided). The rest of the code simply loops through the bit sequence, converting the 1's and 0's to !'s and whitespace and printing one character at a time.
Less obfuscated version:
#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;
}
The strange clever part is in the putchar
statements. Take the first putchar
. ASCII 'Z'
is 90 in decimal, so 90 / 9 = 10 which is a newline character. In the second, decimal 33 is ASCII for '!'
. Toggling the low-order bit of 33 gives you 32, which is ASCII for a space. This causes !
to be printed if b
is odd, and a blank space to be printed if b
is even. The rest of the code is simply there to walk the "pointer" a
through the string.