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)}
まあ、それは動作しますが、これはこのための最良のアプローチではないかもしれないことを認識しています。私は4つしか使っていないので、5番目の安価な手紙が何のためにあるのか分かりません。
これらは1回限りの使用です。2番目のコードを入力する場合は、それらを再起動する必要があります。エンコードする入力には、コンマの後のスペースが必要です。
私が考えたこと
私の最初の質問は、「デコーダーがこれらの4つの文字から何を得ることができるか?」でした。(私はそれらをa、b、c、dと呼びます)、私の最初のアイデアは次の関係から6ビットの情報を取得することでした:
a>b
a>c
a>d
b>c
b>d
c>d
うわー、6ビット、それは完璧です!私はそれが天才だと思ったが、テストはこれがうまくいかないことを示した。可能な組み合わせは24のみです。くそー。
次のステップは、私がすでに知っていたことに基づいて、数えようとすることでした。したがって、文字列に現れる最初の文字は0になり、文字列に挿入される2番目の文字は1になります。しかし、必要な62の組み合わせに到達することはできません。
0000
0001
0010
0011
0012
0100
0101
0102
0110
0111
0112
0120
0121
0122
0123
しかし、私はとにかくアイデアが好きです。
それで、入力の文字が既にリレーションを持っているので、これら2つを組み合わせることができ、値を与えるためにそれらが導入されるまで待つ必要がないので、私は驚いた。
使い方
注:これはゴルフバージョンの正確な動作ではなくなりましたが、原則は変わりません。
デコーダーの場合:
配列にインデックスが含まれ、そのインデックスには4桁の数字がすべて含まれ、その数字の最大桁数はその数字の個別の桁数より大きくありません。その条件を満たす75の異なる4桁の番号があります。これまでのところ、それらを構築する方法がわからなかったので、私はそれらをブルートフォースしました。これらを見つけている間、私はそれらに高価なキャラクターをアスキー的順序で割り当てます。
次に、入力文字列のすべての文字を数字に置き換えます。最小(たとえば、「a」よりも「B」が小さい)が1になり、2番目に小さいものが2になるなど、最大4になります。もちろん、入力に含まれる異なる文字数、結果の文字列になります。
次に、その文字列をインデックスとして持つ配列要素を単に印刷します。
エンコーダはそれに応じて機能します。
使い方
awk bash行コマンドでコードを直接コピーするか、「encode.awk」と「decode.awk」の2つのファイルを作成し、それに応じてコードを貼り付けます。または、次のコードを使用することをお勧めします。このコードは、en / decodingの後に自動的に終了するか、最後のexitコマンドを削除して複数回使用できます。
encode.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
}
decode.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
私はこれをプログラミングのパズルとしてもっと見ました。よく文書化された読みやすいコードから多くのことを学ぶことができるので、ここのほとんどすべてがゴルフであるのは少し悲しいと思いますが、それは私の意見です。そして、私は要求されたようにそれをゴルフしました;)