IOCCC 大赛全称:The International Obfuscated C Code Contest,国际 C 语言混乱代码大赛,目的是写出最有创意的最让人难以理解的 C 语言代码,并限制在 4 kb 以内。这项赛事也年头了,2020 年是第 27 次举办。
#include <stdio.h>
#define N(a) "%"#a"$hhn" #define O(a,b) "%10$"#a"d"N(b) #define U "%10$.*37$d" #define G(a) "%"#a"$s" #define H(a,b) G(a)G(b) #define T(a) a a #define s(a) T(a)T(a) #define A(a) s(a)T(a)a #define n(a) A(a)a #define D(a) n(a)A(a) #define C(a) D(a)a #define R C(C(N(12)G(12))) #define o(a,b,c) C(H(a,a))D(G(a))C(H(b,b)G(b))n(G(b))O(32,c)R #define SS O(78,55)R "\n\033[2J\n%26$s"; #define E(a,b,c,d) H(a,b)G(c)O(253,11)R G(11)O(255,11)R H(11,d)N(d)O(253,35)R #define S(a,b) O(254,11)H(a,b)N(68)R G(68)O(255,68)N(12)H(12,68)G(67)N(67)
char* fmt = O(10,39)N(40)N(41)N(42)N(43)N(66)N(69)N(24)O(22,65)O(5,70)O(8,44)N( 45)N(46)N (47)N(48)N( 49)N( 50)N( 51)N(52)N(53 )O( 28, 54)O(5, 55) O(2, 56)O(3,57)O( 4,58 )O(13, 73)O(4, 71 )N( 72)O (20,59 )N(60)N(61)N( 62)N (63)N (64)R R E(1,2, 3,13 )E(4, 5,6,13)E(7,8,9 ,13)E(1,4 ,7,13)E (2,5,8, 13)E( 3,6,9,13)E(1,5, 9,13)E(3 ,5,7,13 )E(14,15, 16,23) E(17,18,19,23)E( 20, 21, 22,23)E (14,17,20,23)E(15, 18,21,23)E(16,19, 22 ,23)E( 14, 18, 22,23)E(16,18,20, 23)R U O(255 ,38)R G ( 38)O( 255,36) R H(13,23)O(255, 11)R H(11,36) O(254 ,36) R G( 36 ) O( 255,36)R S(1,14 )S(2,15)S(3, 16)S(4, 17 )S (5, 18)S(6, 19)S(7,20)S(8, 21)S(9 ,22)H(13,23 )H(36, 67 )N(11)R G(11)""O(255, 25 )R s(C(G(11) ))n (G( 11) )G( 11)N(54)R C( "aa") s(A( G(25)))T (G(25))N (69)R o (14,1,26)o( 15, 2, 27)o (16,3,28 )o( 17,4, 29)o(18 ,5,30)o(19 ,6,31)o( 20,7,32)o (21,8,33)o (22 ,9, 34)n(C(U) )N( 68)R H( 36,13)G(23) N(11)R C(D( G(11))) D(G(11))G(68)N(68)R G(68)O(49,35)R H(13,23)G(67)N(11)R C(H(11,11)G( 11))A(G(11))C(H(36,36)G(36))s(G(36))O(32,58)R C(D(G(36)))A(G(36))SS
#define arg d+6,d+8,d+10,d+12,d+14,d+16,d+18,d+20,d+22,0,d+46,d+52,d+48,d+24,d\ +26,d+28,d+30,d+32,d+34,d+36,d+38,d+40,d+50,(scanf(d+126,d+4),d+(6\ -2)+18*(1-d[2]%2)+d[4]*2),d,d+66,d+68,d+70, d+78,d+80,d+82,d+90,d+\ 92,d+94,d+97,d+54,d[2],d+2,d+71,d+77,d+83,d+89,d+95,d+72,d+73,d+74\ ,d+75,d+76,d+84,d+85,d+86,d+87,d+88,d+100,d+101,d+96,d+102,d+99,d+\ 67,d+69,d+79,d+81,d+91,d+93,d+98,d+103,d+58,d+60,d+98,d+126,d+127,\ d+128,d+129
char d[538] = {1,0,10,0,10};
int main() { while(*d) printf(fmt, arg); } 以上是小哥哥写的code 代码为71个字节。不过我用GCC并没有编译通过。。。 不知道什么情况
gcc -o prog prog.c 在P1和P2之间交替。输入数字[1-9]移动: 1 | 2 | 3 如果游戏结束,则:
混淆不知道该怎么翻译 该程序的整体包括对printf的单个调用。 int main() { 在这里, 尽管它的主要目的是充当The One True Debugger,但printf也恰好是Turing的完整版。 我们ab ^ H ^使用此事实,完全在此一个printf调用(以及对scanf()的调用以读取用户输入)内完全实现井字逻辑。 这里是(简要地)它是如何工作的。 一开始 该程序使用三个printf格式说明符。
好吧,每个人都可能知道这一点。让我们更高级一些。 格式说明符可以包含额外的“参数”。
例如,以下表达式 printf("%1$.*2$d%3$hhn", 5, 10, &x) 与我们写过的一样 x = 10; 因为它将打印出来 面向Printf的编程好了,现在我们可以享受真正的乐趣了。 我们使用printf进行任意计算,将内存视为二进制数组-每对字节一位:
我们可以使用格式字符串来计算任意“位”的OR / NOT。 我们将从最简单的OR开始: printf("%1$s%2$s%3$hhn", a, b, c) 将计算 *c = strlen(a) + strlen(b) 但假设strlen(x)对于1位是1,对于0位是0,我们有 *c = a | b 计算单个值的NOT也很容易: printf("%1$255d%1$s%hhn", a, b) 将计算 *b = (strlen(a)+255)%256 = strlen(a)-1 再一次,因为 *c = !b 从这里我们可以计算任何二进制电路。但是,高效地做事仍然需要工作。 井字游戏游戏本身被表示为一个18位的棋盘,每个玩家9位,以及在玩家1和玩家2之间交替的转盘计数器。 为了检测谁赢了,我们执行以下逻辑。令A,B和C指向连续测试三个正方形的指针,而D则是是否有获胜的保存位置。 "%A$s%B$s%C$s%1$253d%11$hhn" // r11 = !(*A & *B & *C) 也就是说,我们设置 ZERO宏可确保通过以下表达式写出的字节数为0 mod 256 "%1$hhn%1$s" (repeated 256 times) 其中参数1是指向临时变量的指针,后跟一个空字节。 之所以起作用,是因为如果当前计数为0 mod 256,则“%1 $ hhn”将向参数1写入零,然后“%1 $ s”将永远不会发出任何文本。另一方面,如果计数不是0 mod 256,则将将长度为1的字符串写入参数1,然后“%1 $ s”将使计数增加1。通过重复此256次,我们最终将达到0 mod 256。 类似地,检查是否存在无效移动。 为了确定要打印的内容,我们必须将“内存中”的位数组强制转换为Xs和Os进行打印。这实际上很简单。给定1 $指向玩家1的平方的指针,2 $指向玩家2的平方的指针,以及3 $指向棋盘字符串的指针,我们可以计算 "%1$s" (repeated 47 times) "%2$s" (repeated 56 times) %1$32d%3$hhn" 实际上,它将计算 *r3 = (*r1) * 47 + (*r2) * 56 + 32 如果都不为真,则输出为'',如果r1为真,则输出为'X',如果r2为真,则输出'O'。 进一步的混淆为了能够最终显示面板,同时仍然仅使用一个printf语句,我们使用 "\n\033[2J\n%26$s" 这是清除屏幕的转义序列,然后输出参数26。参数26是指向内存中char *的指针,该指针最初未定义,但是在printf语句中,我们将构造此字符串,使其看起来像tic-tac -脚趾板。 在木板之后,我们需要打印以下字符串之一: P1>_ 根据轮到P1或P2进行移动,游戏结束并且有人赢了,或者游戏结束了,这是平局。 事实证明这并不像看起来那样难。使用与之前相同的技巧,将byte设置为 *byte4 = is_win * 'W' + is_tie * 'T' 字节 我们可以即时创建 一种选择是将逻辑实现为 printf() 但这将使我们需要的对printf的调用次数增加一倍。所以我们改为这样实现 while (*ok) { (实际上,我们实际上将它 注意,现在没有initial https://github.com/carlini/printf-tac-toe 源地址,自己去玩
|
|