Динамічний кодер ASCII!


16

Вступ

Деякі символи ASCII просто такі дорогі в наші дні ...

Щоб заощадити гроші, ви вирішили написати програму, що кодує дорогі символи, використовуючи недорогі.

Однак ціни на символи часто змінюються, і ви не хочете змінювати свою програму кожен раз, коли вам потрібно кодувати або декодувати інший символ! Вам знадобиться більш динамічне рішення.

Виклик

Ваше завдання - написати дві програми: кодер і декодер .

Кодер повинен приймати список з п'яти недорогих персонажів, і один дорогий характер.

Він повинен вивести одну рядок, що складається з недорогих символів, що кодує дорогий символ.

Цей рядок може бути не довше 4 символів , щоб залишатись недорогим. Однак не потрібно використовувати всі недорогі символи в кодуванні, а кодування може бути різної довжини.


Декодер повинен приймати рядок , що видається кодером, і висновок дорогою символів.

Декодер не повинен приймати жодне введення, крім закодованого рядка. Він повинен працювати, немодифікований, з виходу кодера для будь-якої (дійсної) комбінації входів. Іншими словами, ваша програма декодера не знає, які символи дорогі чи недорогі.

Оцінка балів

Найкоротший комбінований код виграє!

Примітки

  • Усі символи будуть великими літерами [A-Z], малими літерами [a-z]або цифрами [0-9].

  • Список недорогих символів не містить дублікатів. Жоден персонаж не буде і недорогим, і дорогим.

  • Кодер і декодер не повинні писатися однією мовою, але вони можуть бути. Ви можете написати програму або функцію.

  • Введення та вихід можуть бути у будь-якому розумному для вашої мови форматі.

  • Дві програми можуть не надавати жодних змінних чи даних.

Підсумок

  • Кодування даються деякі недорогі символи та дорогий символ.

  • Енкодер виводить рядок недорогих символів, кодуючи дорогий символ.

  • Декодеру надається вихід кодера і видається дорогий характер.

Приклади

Вхід:     a, b, c, d, e     f

Можливості кодера:     a     eeee     caec

Декодер:     f


Вхід:     a, b, c, d, e     h

Можливості кодера:     bc     cea     eeaa

Декодер:     h


Вхід:     q, P, G, 7, C     f

Можливості кодера:     777     P7     PPCG

Декодер:     f


Це справді може бути я, і я вибачаюся за це питання, якщо воно є, але як саме ви повинні кодувати ваше повідомлення недорогими символами? Додавання ASCII кодів для 5 недорогих символів? Власне, це питання має лише підставу, якщо ваш декодер повинен розшифрувати всі створені можливості кодування.
Коул

Щоб було зрозуміло: можливості Енкодера - це лише приклади, і ми можемо кодувати кожен символ так, як хочемо, так?
Денніс

@Dennis Так, це лише приклади.
jrich

@Cole Не роздаючи власне алгоритм , оскільки це головна проблема, я вважаю, що це можливо. Є лише 62 можливі дорогі літери для кодування, і за допомогою цих 4 символів ascii до 92 можна закодувати, згідно з A239914 . (величезне спасибі коментарям пісочниці PhiNotPi для цього - я не підрахував точно, скільки їх можна закодувати)
jrich

@UndefinedFunction Я тепер усвідомлюю те, що ви задумали: на питання Денніса відповів, що мене бентежить.
cole

Відповіді:


5

Pyth, 46 байт

Енкодер, 22 байти

@smfql{Td^<Szd4S4-Cw48

Декодер, 24 байти

C+48xsmfql{Td^<sS{zd4S4z

Нічого собі, це ідеально підходить. 75 різних комбінацій char та 75-ти діапазон
Jakube

Я думаю , ви можете замінити S4з Tі зберегти кожен один байт в обох програмах.
Якубе

7

CJam, 55 50 48 47 байт

Енкодер, 24 22 21 байт

l$:L4m*{$L|L=},rc'0-=

Спробуйте в Інтернеті.

Дешифратор, 31 28 27 26 байт

4_m*{$4,|4,=},l_$_|f#a#'0+

Спробуйте в Інтернеті.


Чи є там ви використовуєте аркуш синтаксису CJam? Один на sourceforge та інший чіт-лист у форматі PDF не містять усіх символів, якими ви користуєтесь'
Luminous

'не є оператором. Ви можете знайти його на сторінці синтаксису .
Денніс

4

гаук, 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

Я бачив це більше як головоломка програмування. Я думаю, що це сумно, що майже все тут є полем для гольфу, тому що ви можете дізнатися багато іншого з добре задокументованого, читабельного коду, але це лише моя думка. І я гольфував так, як просили;)


як це перевірити? будь ласка, поділіться кількома прикладами.
Шраван Ядав

+1 за велике пояснення! Здається, існує багато різних способів підходу до цієї проблеми :)
jrich

1
Це було дуже схоже на мій процес мислення, за винятком того, що я не усвідомлював грубих форсировань унікальних слабких комбінацій (де ви описали, що найбільша цифра не перевищує кількість цифр) була життєздатним підходом. Кудо для подальшого проходження.
Патрік Робертс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.