гаук, 163 + 165 = 328
Тестується з gawk 4.1.1, але він повинен працювати і в старих версіях gawk. Для роботи з мавкою потрібно трохи змінити (подовжити).
кодер (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 символів?" (Я буду називати їх 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 різних чотиризначних чисел. Я жорстоко змушую їх, тому що поки що я не міг придумати спосіб їх побудови, і я не впевнений, що це було б коротше, як це зробити. Хоча я знаходжу їх, я присвоюю їм дорогі персонажі в асибетичному порядку.
Потім я замінюю кожен символ із вхідного рядка цифрою. Найменший (наприклад, "B" менше, ніж "a") стає 1, другий найменший стає 2, і так далі до 4. Звичайно, це залежить від того, скільки різних знаків у введенні, яка найвища цифра в отриманий рядок буде.
Тоді я просто надрукую елемент масиву, який містить цей рядок як індекс.
Кодер працює відповідно.
Як користуватись
Або скопіюйте код безпосередньо в команду awk bash line або зробіть два файли "encode.awk" та "decode.awk" та вставте код відповідно. Або ще краще використовувати наступний код, який автоматично закривається після en / декодування, або може бути використаний кілька разів, видаляючи команду 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
Я бачив це більше як головоломка програмування. Я думаю, що це сумно, що майже все тут є полем для гольфу, тому що ви можете дізнатися багато іншого з добре задокументованого, читабельного коду, але це лише моя думка. І я гольфував так, як просили;)