gawk, 163 + 165 = 328
Gawk 4.1.1 ile test edilmiştir, ancak eski gawk sürümlerinde de çalışmalıdır. Mawk ile çalışmak için biraz değiştirilmesi (uzatılması) gerekir.
kodlayıcı (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]]}
kod çözücü (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)}
İşe yarıyor, ama bunun bunun için en iyi yaklaşım olmayabileceğinin farkındayım. Beşinci ucuz mektubun ne için olduğu hakkında hiçbir fikrim yok, çünkü sadece dört tane kullanıyorum.
Bunlar sadece tek kullanımlıktır. İkinci bir kod girmek isterseniz, bunları yeniden başlatmanız gerekir. Kodlama için girişte virgüllerden sonraki boşluklar gereklidir.
Hakkında ne düşündüm
İlk sorum "Bu 4 karakterden bir kod çözücü ne elde edebilirdi?" (Onlara a, b, c ve d diyeceğim) ve ilk fikrim aşağıdaki ilişkilerden 6 bit Bilgi almaktı:
a>b
a>c
a>d
b>c
b>d
c>d
Vay canına, 6 bit, bu mükemmel! Bunun dahi olduğunu düşündüm, ancak testler bunun işe yaramayacağını gösterdi. Sadece 24 olası kombinasyon vardır. Lanet olsun.
Bir sonraki adım, zaten bildiklerime dayanarak saymaya çalışıyordu. Böylece, dizede görünen ilk harf 0 olur, sonra dizeye eklenen ikinci harf 1 olur ve bu şekilde devam eder. Ama bu beni gereken 62 kombinasyona kadar getirmeyecekti.
0000
0001
0010
0011
0012
0100
0101
0102
0110
0111
0112
0120
0121
0122
0123
Ama yine de fikri seviyorum.
O zaman bu ikisini birleştirebileceğim beni vurdu, çünkü girişteki karakterlerin zaten ilişkileri var ve onlara bir değer vermek için tanıtılıncaya kadar beklemek zorunda kalmayacaktım.
Nasıl çalışır
Not: Bu artık golf versiyonlarının tam olarak nasıl çalıştığı değil, prensip aynı kaldı.
Kod çözücü için:
Dizini, en büyük basamağı bu sayıdaki ayrı basamak sayısından büyük olmayan dört basamaklı sayıların tümünü içeren bir dizi oluşturulur. Bu koşulu karşılayan 75 farklı dört basamaklı sayı vardır. Onları zorluyorum, çünkü şimdiye kadar onları inşa etmenin bir yolunu bulamadım ve bunun awk içinde yapmanın daha kısa olacağından emin değilim. Bunları bulduğumda onlara pahalı karakterleri asciibetik sırayla atarım.
Sonra girdi dizesindeki her karakteri bir rakamla değiştiriyorum. En küçük (örneğin 'a' dan 'B' küçüktür) 1 olur, en küçük ikinci 2 olur ve bu şekilde 4 olur. Tabii ki girişte kaç farklı karakter olduğuna, en yüksek rakamın ortaya çıkan dize olacaktır.
Sonra sadece bu dizeyi bir dizin olarak içeren dizi elemanını yazdırıyorum.
Kodlayıcı buna göre çalışır.
Nasıl kullanılır
Kodu doğrudan bir awk bash line komutuna kopyalayın veya iki dosya "encode.awk" ve "decode.awk" yapın ve kodu uygun şekilde yapıştırın. Ya da en / kod çözme işleminden sonra otomatik olarak çıkan veya sonunda çıkış komutunu kaldırarak birden çok kez kullanılabilen aşağıdaki kodu daha iyi kullanın.
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
}
İşte bir kullanım örneği:
me@home:~/$ awk -f encode.awk
w, 0, R, 1, d X
10R1
me@home:~/$ awk -f decode.awk
10R1
X
Golf versiyonlarını kullanırsanız, her virgülden sonra boşluk bırakılması gerektiğini unutmayın.
İsterseniz, bu kısa ve kirli komut dosyasını bazı örnek veriler oluşturmak için kullanabilirsiniz
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)
}
}
ve komik bir şey yap
me@home:~/$ awk -f gen.awk|awk -f encode.awk|awk -f decode.awk|sort -u|wc -l
62
Bunu daha çok bir programlama bulmacası olarak gördüm. Bence biraz üzücü, buradaki hemen hemen her şey golf oynuyor, çünkü iyi belgelenmiş, okunabilir koddan çok daha fazlasını öğrenebilirsiniz, ama bu sadece benim düşüncem. Ve ben istendiği gibi golf;)