Bunu gizleyelim.
Hizalama:
main(_) {
_^448 && main(-~_);
putchar(--_%64
? 32 | -~7[__TIME__-_/8%8][">'txiZ^(~z?"-48] >> ";;;====~$::199"[_*2&8|_/64]/(_&2?1:8)%8&1
: 10);
}
Bu karışıklığı çözmek için değişkenlerle tanışın:
main(int i) {
if(i^448)
main(-~i);
if(--i % 64) {
char a = -~7[__TIME__-i/8%8][">'txiZ^(~z?"-48];
char b = a >> ";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8;
putchar(32 | (b & 1));
} else {
putchar(10); // newline
}
}
-~i == i+1
İki tamamlayıcı nedeniyle unutmayın . Bu nedenle,
main(int i) {
if(i != 448)
main(i+1);
i--;
if(i % 64 == 0) {
putchar('\n');
} else {
char a = -~7[__TIME__-i/8%8][">'txiZ^(~z?"-48];
char b = a >> ";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8;
putchar(32 | (b & 1));
}
}
Şimdi, bununla a[b]
aynıb[a]
olduğuna dikkat edin ve -~ == 1+
değişikliği tekrar uygulayın :
main(int i) {
if(i != 448)
main(i+1);
i--;
if(i % 64 == 0) {
putchar('\n');
} else {
char a = (">'txiZ^(~z?"-48)[(__TIME__-i/8%8)[7]] + 1;
char b = a >> ";;;====~$::199"[(i*2&8)|i/64]/(i&2?1:8)%8;
putchar(32 | (b & 1));
}
}
Özyinelemeyi bir döngüye dönüştürme ve biraz daha basit bir şekilde gizleme:
// please don't pass any command-line arguments
main() {
int i;
for(i=447; i>=0; i--) {
if(i % 64 == 0) {
putchar('\n');
} else {
char t = __TIME__[7 - i/8%8];
char a = ">'txiZ^(~z?"[t - 48] + 1;
int shift = ";;;====~$::199"[(i*2&8) | (i/64)];
if((i & 2) == 0)
shift /= 8;
shift = shift % 8;
char b = a >> shift;
putchar(32 | (b & 1));
}
}
}
Bu, yineleme başına bir karakter çıkarır. Her 64 karakterde bir satırsonu çıkar. Aksi takdirde, neyin verileceğini anlamak için bir çift veri tablosu kullanır ve karakter 32 (boşluk) veya karakter 33 (a !
) koyar . İlk tablo ( ">'txiZ^(~z?"
), her karakterin görünümünü açıklayan 10 bitmap'lerden oluşan bir kümedir ve ikinci tablo ( ";;;====~$::199"
), bitmapten görüntülemek için uygun biti seçer.
İkinci tablo
İkinci tabloyu inceleyerek başlayalım int shift = ";;;====~$::199"[(i*2&8) | (i/64)];
. i/64
satır numarası (6 ila 0) ve i*2&8
8 iff i
, 4, 5, 6 veya 7 mod 8'dir.
if((i & 2) == 0) shift /= 8; shift = shift % 8
tablo değerinin yüksek sekizlik basamağını ( i%8
= 0,1,4,5 için) veya düşük sekizli basamağını ( i%8
= 2,3,6,7 için) seçer . Vardiya tablosu şöyle görünür:
row col val
6 6-7 0
6 4-5 0
6 2-3 5
6 0-1 7
5 6-7 1
5 4-5 7
5 2-3 5
5 0-1 7
4 6-7 1
4 4-5 7
4 2-3 5
4 0-1 7
3 6-7 1
3 4-5 6
3 2-3 5
3 0-1 7
2 6-7 2
2 4-5 7
2 2-3 3
2 0-1 7
1 6-7 2
1 4-5 7
1 2-3 3
1 0-1 7
0 6-7 4
0 4-5 4
0 2-3 3
0 0-1 7
veya tablo şeklinde
00005577
11775577
11775577
11665577
22773377
22773377
44443377
Yazarın ilk iki tablo girdisi için null sonlandırıcı kullandığını unutmayın (gizli!).
Bu, yedi segmentli bir ekrandan sonra, 7
boşluklar olarak tasarlanmıştır. Bu nedenle, ilk tablodaki girdiler yanan segmentleri tanımlamalıdır.
İlk tablo
__TIME__
önişlemci tarafından tanımlanan özel bir makrodur. Ön işlemcinin çalıştırıldığı zamanı içeren bir dize sabitine genişler "HH:MM:SS"
. Tam olarak 8 karakter içerdiğine dikkat edin. 0-9'un ASCII değerleri 48 ila 57 ve :
ASCII değeri 58 olduğunu unutmayın. Çıktı satır başına 64 karakterdir, böylece karakter başına 8 karakter bırakır __TIME__
.
7 - i/8%8
dolayısıyla __TIME__
, şu anda çıktısı alınmakta olan endeksidir ( aşağı doğru 7-
tekrarladığımız için gereklidir i
). Yani, çıktı olmanın t
karakteri __TIME__
.
a
girişe bağlı olarak ikili olarak aşağıdakine eşit olur t
:
0 00111111
1 00101000
2 01110101
3 01111001
4 01101010
5 01011011
6 01011111
7 00101001
8 01111111
9 01111011
: 01000000
Her sayı, yedi bölümlü ekranımızda yanan bölümleri açıklayan bir bitmaptir . Karakterlerin hepsi 7 bit ASCII olduğundan, yüksek bit her zaman temizlenir. Böylece, 7
segment tablosunda her zaman boş olarak yazdırılır. İkinci tablo 7
boşluklar olarak s ile şöyle görünür :
000055
11 55
11 55
116655
22 33
22 33
444433
Bu nedenle, örneğin, 4
bir 01101010
(bit 1, 3, 5, ve 6, set), baskılar olarak
----!!--
!!--!!--
!!--!!--
!!!!!!--
----!!--
----!!--
----!!--
Kodu gerçekten anladığımızı göstermek için, bu tabloyla çıktıyı biraz ayarlayalım:
00
11 55
11 55
66
22 33
22 33
44
Bu olarak kodlanır "?;;?==? '::799\x07"
. Sanatsal amaçlar için, birkaç karaktere 64 ekleyeceğiz (sadece düşük 6 bit kullanıldığından, bu çıktıyı etkilemez); bu verir "?{{?}}?gg::799G"
(8. karakterin kullanılmadığına dikkat edin, böylece aslında istediğimizi yapabiliriz). Yeni masamızı orijinal koda koyarak:
main(_){_^448&&main(-~_);putchar(--_%64?32|-~7[__TIME__-_/8%8][">'txiZ^(~z?"-48]>>"?{{?}}?gg::799G"[_*2&8|_/64]/(_&2?1:8)%8&1:10);}
aldık
!! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !!
tam beklediğimiz gibi. Orijinal kadar sağlam görünmüyor, bu da yazarın neden yaptığı masayı kullanmayı seçtiğini açıklıyor.
printf("%d", _);
başına eklememain
: pastebin.com/HHhXAYdJ