gawk,163 + 165 = 328
在gawk 4.1.1上进行了测试,但也应在较早的gawk版本中工作。需要稍作修改(加长)才能与mawk一起使用。
编码器(163):
{for(gsub(", ",_);sprintf("%c",++r)!=$NF;asort(a))split($1,a,_);r-=r>64?53:46;for(k=4^5;r-=_~i;j=_)for(i=++k;gsub(++j,_,i);)split(k,b,_);for(j in b)printf a[b[j]]}
解码器(165):
{split($1,a,_);for(i in a)d[a[i]]=a[i];asort(d);for(k=4^5;c!~$1;x+=_~i){i=++k;for(c=j=_;gsub(++j,_,i);split(k,b,_));for(g in b)c=c d[b[g]]}printf"%c",x+(x>10?54:47)}
是的,它可以工作,但是我知道这可能不是最好的方法。我不知道第五个廉价字母是什么意思,因为我只使用了四个。
这些仅用于单次使用。如果要输入第二个代码,则必须重新启动它们。输入中需要使用逗号后的空格进行编码。
我的想法
我的第一个问题是“解码器从这四个字符中能得到什么?” (我将它们称为a,b,c和d),最初的想法是从以下关系中获取6位信息:
a>b
a>c
a>d
b>c
b>d
c>d
哇,6位,太完美了!我以为是天才,但测试表明这行不通。只有24种可能的组合。该死的。
下一步是根据我已经知道的内容尝试计算。因此,出现在字符串中的第一个字母将变为0,然后出现在字符串中的第二个字母将变为1,依此类推。但这并不能带我达到所需的62种组合。
0000
0001
0010
0011
0012
0100
0101
0102
0110
0111
0112
0120
0121
0122
0123
但是我还是喜欢这个主意。
好吧,然后让我吃惊的是,我可以将这两者结合起来,因为输入中的字符已经具有关联性,而我不必等到引入它们来给它们赋值时才开始。
怎么运行的
注意:这不再是高尔夫球版本的工作原理,但原理保持不变。
对于解码器:
构造一个数组,其索引包含所有四位数,其最大位数不大于该位数中的不同位数。有75个满足该条件的四个数字。我蛮力地使用它们,因为到目前为止我还无法找到一种构造它们的方法,而且我不确定这在awk中会更短一些。当我找到这些字符时,我按字母顺序将它们分配给了昂贵的字符。
然后,我用数字替换输入字符串中的每个字符。最小的(例如,“ B”小于“ a”)变为1,第二个最小变为2,依此类推,直到4。当然,这取决于输入中有多少个不同的字符,输入的最高位数是多少。结果字符串将是。
然后,我简单地打印具有该字符串作为索引的数组元素。
编码器将相应地工作。
如何使用
直接在awk bash行命令中复制代码,或制作两个文件“ encode.awk”和“ decode.awk”并相应地粘贴代码。甚至更好地使用以下代码,该代码在编码/解码后自动退出,或者可以通过删除结尾的退出命令来多次使用。
编码.awk
{
if(!x) # only do first time
for(i=1e3;i++<5e3;delete a)
{
for(m=j=0;p=substr(i,++j,1);p>m?m=p:0)++a[p];
length(a)>=m&&i!~0?c[(x>9?55:48)+x++]=i:_
}
r=u=_; # clear reused variables
for(gsub(",",FS);sprintf("%c",++r)!=$NF;); # more flexible concerning
--NF; # spaces in input
split($0,b);
asort(b);
split(c[r],a,_);
for(j in a)u=u b[a[j]]; # prettier printing than golfed version
print u
exit # <=== remove to encode input file
}
解码.awk
{
if(!x) # only do first time
for(i=1e3;i++<5e3;delete a)
{
for(m=j=0;p=substr(i,++j,1);p>m?m=p:_)++a[p];
length(a)>=m&&i!~0?c[i]=sprintf("%c",(x>9?55:48)+x++):_
}
delete t; delete d; o=_; # clear reused variables
split($1,a,_);
for(i in a)t[a[i]]=1;
for(i in t)d[++y]=i;
asort(d);
for(i in a)for(j in d)if(d[j]~a[i])o=o j;
print c[o]
exit # <=== remove to encode input file
}
这是一个用法示例:
me@home:~/$ awk -f encode.awk
w, 0, R, 1, d X
10R1
me@home:~/$ awk -f decode.awk
10R1
X
请记住,如果使用高尔夫球版本,则每个逗号后都需要空格。
如果需要,可以使用这个简短又脏的脚本来生成一些样本数据
BEGIN{
for(srand();i++<1000;)
{
erg="";
for(j=0;j++<5;)
{
while(erg~(a[j]=substr(c="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",rand()*62+1,1)));
erg=erg a[j]
}
print a[1]", "a[2]", "a[3]", "a[4]", "a[5](rand()>.5?" ":rand()>.5?" ":" ")substr(c,rand()*62+1,1)
}
}
做一些有趣的事情
me@home:~/$ awk -f gen.awk|awk -f encode.awk|awk -f decode.awk|sort -u|wc -l
62
我更多地将其视为编程难题。我觉得有点遗憾,因为这里几乎所有内容都是高尔夫球,因为您可以从有据可查的可读代码中学到更多东西,但这只是我的观点。我按照要求打了高尔夫球;)