此代码如何生成印度地图?


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
有关此类更有趣的代码,请参见[国际混淆式C代码竞赛] [ ioccc.org/]
DarkDust

12
只是要知道,代码是故意很难理解的,因此,从初学者的水平学习C并没有多大好处。
泰勒·麦克亨利

Answers:


154

长字符串只是转换为ASCII的二进制序列。第一个for语句b从10开始,在[b+++21]字符串之后产生31。将字符串视为数组,偏移量31是字符串中“实际”数据的开始(您提供的代码示例的第二行)。其余代码仅循环遍历位序列,将1和0转换为!和空格,并一次打印一个字符。

不太混淆的版本:

#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'是十进制的90,因此90/9 = 10,这是换行符。在第二个中,十进制的33是的ASCII '!'。切换33的低阶位可得到32,即空格的ASCII码。!如果b是奇数,将导致打印,如果是偶数,将导致打印空白b。其余的代码只是在其中引导“指针” a遍历字符串。


22
该字符串不是位序列(请注意,代码中没有位移操作)。它是图像的行程编码。
interjay

89

基本上,字符串是图像的行程编码:字符串中的交替字符表示连续绘制几次,以及连续绘制感叹号的次数。这是对该程序不同元素的分析:

编码字符串

该字符串的前31个字符将被忽略。其余部分包含绘制图像的说明。各个字符确定要连续绘制多少个空格或感叹号。

外循环

此循环遍历字符串中的字符。每次迭代都会将的值b加1,然后将字符串中的下一个字符分配给a

内循环

此循环绘制单个字符,并在到达行尾时绘制换行符。绘制的字符数为a - 64。的值c从10到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 2014年

3
@PankajMahato因为b在10开始并且索引是(b++)+21,其开始于31
interjay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.