Bagaimana kode ini menghasilkan peta India?

169

Kode ini mencetak peta India. Bagaimana cara kerjanya?

#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;
}
narayanpatra
sumber
63
Ini hanya dikaburkan C ... ada seluruh masyarakat yang didedikasikan untuk kegilaan semacam ini.
Mark
12
Keluaran: codepad.org/ngiITeZ4
Andreas Rejbrand
2
#include "Stdio.h": Apakah itu berfungsi pada semua kompiler? Saya terkejut melihat bahwa Anda bisa mendapatkan kode yang berfungsi dengan miscaps. Mungkin itu pada Windows (non case sensitive FS)
alternatif
2
Untuk kode yang lebih menyenangkan seperti itu lihat [Kontes Kode C Internasional Yang Tidak Jelas] [ ioccc.org/] .
DarkDust
12
Perlu diketahui bahwa kode ini sengaja sulit dipahami, dan tidak banyak yang bisa diperoleh dari memahaminya, sejauh mempelajari C dari tingkat pemula.
Tyler McHenry

Jawaban:

154

String panjang hanyalah urutan biner yang dikonversi ke ASCII. forPernyataan pertama membuat bmulai dari 10, dan [b+++21]setelah string menghasilkan 31. Memperlakukan string sebagai array, offset 31 adalah awal dari data "nyata" dalam string (baris kedua dalam sampel kode yang Anda berikan). Sisa kode hanya loop melalui urutan bit, mengubah 1 dan 0 ke! Dan spasi dan mencetak satu karakter pada suatu waktu.

Versi yang kurang dikaburkan:

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

Bagian pintar yang aneh ada di putcharpernyataan. Ambil yang pertama putchar. ASCII 'Z'adalah 90 dalam desimal, jadi 90/9 = 10 yang merupakan karakter baris baru. Di kedua, desimal 33 adalah ASCII untuk '!'. Mengubah bit orde rendah dari 33 memberi Anda 32, yang merupakan ASCII untuk spasi. Ini menyebabkan !dicetak jika baneh, dan ruang kosong dicetak jika bgenap. Sisa kode hanya ada di sana untuk berjalan "pointer" amelalui string.

bta
sumber
22
String bukan urutan bit (perhatikan bahwa tidak ada operasi bit-shift dalam kode). Ini adalah pengkodean run-length dari gambar.
interjay
89

Pada dasarnya, string adalah pengkodean run-length dari gambar: Karakter bergantian dalam string mengatakan berapa kali untuk menggambar spasi, dan berapa kali untuk menggambar tanda seru secara berurutan. Berikut ini adalah analisis dari berbagai elemen program ini:

String yang disandikan

31 karakter pertama dari string ini diabaikan. Selebihnya berisi instruksi untuk menggambar gambar. Karakter individu menentukan berapa banyak spasi atau tanda seru untuk menggambar secara berurutan.

Luar untuk loop

Loop ini melewati karakter dalam string. Setiap iterasi meningkatkan nilai bsatu, dan menetapkan karakter berikutnya dalam string a.

Batin untuk loop

Loop ini menarik karakter individu, dan baris baru setiap kali mencapai akhir baris. Jumlah karakter yang diambil adalah a - 64. Nilai cdari 10 hingga 90, dan ulang ke 10 ketika akhir garis tercapai.

Itu putchar

Ini dapat ditulis ulang sebagai:

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

Ini menarik karakter yang sesuai, tergantung pada apakah bgenap atau ganjil, atau baris baru saat diperlukan.

interjay
sumber
1
Mengapa 31 karakter pertama diabaikan?
Pankaj Mahato
3
@PankajMahato karena bdimulai pada 10 dan indeksnya (b++)+21, yang dimulai pada 31.
interjay