我刚刚在StackOverflow上看到了Obfuscated C解释的解释。我发现比赛非常有趣,因为我每天都要学习新的C,而且每天都有新的编程知识。
一个有趣的是Explain 1-liner party of a US President from IOCCC 2013
如您所见,该程序使用一系列模数函数(即。(整数)%4796%275%4)来散列输入数字以形成两个输出数字之一。这"哈希"功能已被试验并且错误地为一组有限的输入正确工作。
我认为最大限度地减少程序的大小是件好事,这样你就可以将一个结果映射到另一个结果。例如,你可以将{apple,lettuce,carrot,pear,orange,asparagus}转换为数字并通过函数,转换为{1,0,0,1,1,0},这个函数少花了空间比完整的数据库搜索字符串并确定其果实。
所以我的问题是......你如何创建一个程序来强制堆叠的模数函数,这些函数适用于所有给定的输入集和输出集?
继续水果示例,您可以将水果的前两个字母转换为如下数字: apple - > ap - > 0x6170
所以列表变为{0x6170,0x6c65,0x6361,0x7065,0x6f72,0x6173}
所以你想生成一个包含重复模的函数来将{0x6170,0x6c65,0x6361,0x7065,0x6f72,0x6173}映射到{1,0,0,1,1,0}
怎么会这样做?
答案 0 :(得分:0)
有趣的挑战,但超越了我的数学技能。所以,这是一个简单的C :P
我没有数学证明,因此无法证明这将总是找到解决方案,但它适用于您的输入。添加“水果”“克林顿”和“蔬菜”“麦卡因”使其运行时间更长;添加“杏”将发出冲突信号! (已报道,但没有说明在哪里。请注意,类似的项目内的冲突 - fruits 或蔬菜 - 实际上应该被允许。我没有写代码为此,但它应该相对简单。)
要查看更长的序列,请添加“banana”。出于某种原因,这需要达到163,13,2
。有趣的是,然后添加“金橘”(我的水果已用完)并不需要太长时间,即使使用另一种“椰子”也不会花费太多时间。
实施说明:
您可以将搜索限制为最大输入2字节代码,因为mod
函数永远不会对较大的数字执行任何操作。为了保持一致性,这个C代码从测试所有1-mod值开始(尽管我没有找到任何有用的东西)。然后它测试2-mod值,最后测试3-mod值。如果它没有找到值,你可以扩展它以寻找4-mod和5-mod长序列,但搜索时间将以对数方式增加(!)。
应该可以对超过2个值进行分类;这需要非常小的代码重写。我怀疑为所有人寻找一场比赛需要更长的时间。
还应该可以返回除0
和1
之外的其他“索引”;正如我写的那样,其余的CPU正在2
和0
上努力工作。但是,这似乎需要相当长的时间。
C实施,蛮力:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char *fruits[] = { "apple", "pear", "orange"} ; //, "clinton" };
char *veggies[] = { "lettuce", "carrot", "asparagus" }; // , "mccaine" };
int num_f, num_v, found_match;
unsigned short *code[2], max_code = 0;
int i,j, mod_value1, mod_value2, mod_value3;
num_f = sizeof(fruits)/sizeof(fruits[0]);
num_v = sizeof(veggies)/sizeof(veggies[0]);
code[0] = malloc((num_f+num_v)*sizeof(short));
code[1] = malloc((num_f+num_v)*sizeof(short));
for (i=0; i<num_f; i++)
{
code[0][i] = (fruits[i][0]<<8)+fruits[i][1];
code[1][i] = 1;
if (code[0][i] > max_code)
max_code = code[0][i];
}
for (i=0; i<num_v; i++)
{
code[0][num_f+i] = (veggies[i][0]<<8)+veggies[i][1];
code[1][num_f+i] = 0;
if (code[0][num_f+i] > max_code)
max_code = code[0][num_f+i];
}
for (i=0; i<num_f+num_v; i++)
{
for (j=i+1; j<num_f+num_v; j++)
{
if (code[0][i] == code[0][j])
{
printf ("clash!\n");
exit(-1);
}
}
}
printf ("calculating...\n");
for (mod_value1=1; mod_value1<max_code; mod_value1++)
{
found_match = 1;
for (i=0; i<num_f+num_v; i++)
{
if (code[0][i] % mod_value1 != code[1][i])
{
found_match = 0;
break;
}
}
if (found_match)
{
printf ("mod %d should work\n", mod_value1);
break;
}
}
if (found_match)
{
for (i=0; i<num_f; i++)
{
printf ("%s -> %d\n", fruits[i], code[0][i] % mod_value2 % mod_value1);
}
for (i=0; i<num_v; i++)
{
printf ("%s -> %d\n", veggies[i], code[0][num_f+i] % mod_value2 % mod_value1);
}
} else
{
for (mod_value1=1; mod_value1<max_code; mod_value1++)
{
for (mod_value2=mod_value1+1; mod_value2<max_code; mod_value2++)
{
found_match = 1;
for (i=0; i<num_f+num_v; i++)
{
if (code[0][i] % mod_value2 % mod_value1 != code[1][i])
{
found_match = 0;
break;
}
}
if (found_match)
{
printf ("mod %d mod %d should work\n", mod_value2, mod_value1);
break;
}
}
if (found_match)
break;
}
if (found_match)
{
for (i=0; i<num_f; i++)
{
printf ("%s -> %d\n", fruits[i], code[0][i] % mod_value2 % mod_value1);
}
for (i=0; i<num_v; i++)
{
printf ("%s -> %d\n", veggies[i], code[0][num_f+i] % mod_value2 % mod_value1);
}
} else
{
for (mod_value1=1; mod_value1<max_code; mod_value1++)
{
for (mod_value2=mod_value1+1; mod_value2<max_code; mod_value2++)
{
for (mod_value3=mod_value2+1; mod_value3<max_code; mod_value3++)
{
found_match = 1;
for (i=0; i<num_f+num_v; i++)
{
if (code[0][i] % mod_value3 % mod_value2 % mod_value1 != code[1][i])
{
found_match = 0;
break;
}
}
if (found_match)
{
printf ("mod %d mod %d mod %d should work\n", mod_value3, mod_value2, mod_value1);
break;
}
}
if (found_match)
break;
}
if (found_match)
break;
}
if (found_match)
{
for (i=0; i<num_f; i++)
{
printf ("%s -> %d\n", fruits[i], code[0][i] % mod_value3 % mod_value2 % mod_value1);
}
for (i=0; i<num_v; i++)
{
printf ("%s -> %d\n", veggies[i], code[0][num_f+i] % mod_value3 % mod_value2 % mod_value1);
}
}
}
}
return 0;
}
您原来的3个水果,3个素食列表的结果:
mod 25 mod 2 should work
apple -> 1
pear -> 1
orange -> 1
lettuce -> 0
carrot -> 0
asparagus -> 0
晚期结果,适用于2
和0
的所需输出:
mod 507 mod 8 mod 3 should work
apple -> 2
pear -> 2
orange -> 2
lettuce -> 0
carrot -> 0
asparagus -> 0
后来的结果是,将“有争议的”“番茄”添加为第2类:
mod 103 mod 7 mod 3 should work
apple -> 1
pear -> 1
orange -> 1
lettuce -> 0
carrot -> 0
asparagus -> 0
tomato -> 2