รหัสนี้สร้างแผนที่ของอินเดียได้อย่างไร


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 (ไม่ใช่แบบตัวพิมพ์เล็ก
ทางเลือก

2
รหัสความสนุกสนานมากขึ้นเช่นเห็นว่า [ตอนที่ปกปิด C ประกวดรหัสสากล] [ ioccc.org/]
DarkDust

12
เพิ่งทราบว่ารหัสคือจงใจยากที่จะเข้าใจและมีไม่มากที่จะได้รับจากการหามันออกมาเท่าที่เรียนรู้ C จากระดับเริ่มต้นของความเป็นห่วง
Tyler McHenry

คำตอบ:


154

สตริงที่ยาวเป็นเพียงลำดับไบนารีที่ถูกแปลงเป็น ASCII forคำสั่งแรกbเริ่มต้นที่ 10 และ[b+++21]หลังสตริงให้ผล 31 การรักษาสตริงเป็นอาร์เรย์ offset 31 คือการเริ่มต้นของข้อมูล "ของจริง" ในสตริง (บรรทัดที่สองในตัวอย่างโค้ดที่คุณให้ไว้) ส่วนที่เหลือของรหัสจะวนซ้ำตามลำดับบิตโดยแปลง 1 และ 0 เป็น! 's และช่องว่างและพิมพ์อักขระทีละตัว

รุ่นที่สับสนน้อยกว่า:

#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
สตริงไม่ใช่ลำดับบิต (โปรดทราบว่าไม่มีการดำเนินการบิตกะในรหัส) เป็นการเข้ารหัสความยาวของรูปภาพ
ระหว่าง

89

โดยพื้นฐานแล้วสตริงเป็นการเข้ารหัสความยาวของรูปภาพ: อักขระที่สลับกันในสตริงบอกจำนวนครั้งในการวาดเว้นวรรคและจำนวนครั้งในการวาดเครื่องหมายอัศเจรีย์ต่อเนื่อง นี่คือการวิเคราะห์องค์ประกอบต่าง ๆ ของโปรแกรมนี้:

สตริงที่เข้ารหัส

อักขระ 31 ตัวแรกของสตริงนี้จะถูกละเว้น ที่เหลือมีคำแนะนำสำหรับการวาดภาพ อักขระแต่ละตัวกำหนดจำนวนช่องว่างหรือเครื่องหมายอัศเจรีย์เพื่อวาดติดต่อกัน

ด้านนอกสำหรับห่วง

การวนซ้ำนี้ไปเหนืออักขระในสตริง แต่ละซ้ำเพิ่มมูลค่าของโดยหนึ่งและกำหนดตัวอักษรถัดไปในสตริงba

วงในสำหรับวง

การวนซ้ำนี้จะดึงอักขระแต่ละตัวและขึ้นบรรทัดใหม่เมื่อถึงจุดสิ้นสุดของบรรทัด 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

3
@PankajMahato เพราะbเริ่มต้นที่ 10 และดัชนีคือ(b++)+21ซึ่งเริ่มต้นที่ 31.
interjay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.