Кодування - Переміщення - Розшифровка


23

Виклик

Ваше завдання - кодувати ціле число у вигляді рядка символів ASCII , а потім успішно розшифрувати його після випадкового переміщення зазначеної рядки.

Ви напишете дві програми / функції , які будуть іменуватися Encoder і Decoder .

Енкодер

  • Введення: ціле число у діапазоні .n[0,2311]
  • Висновок: рядок з ASCII символів (не обов'язково для друку).s

Дешифратор

  • Введення: випадкова перестановка рядка .ss
  • Вихід: ціле число .n

Оцінка балів

Нехай бути максимальною довжиною по у всіх можливих значеннях . Якщо Енкодер діє недетерміновано (що дозволено, див. Нижче), то буде максимальною довжиною яка може виникнути (можливо, ).AsnAs

Нехай буде довжиною кодувальника в байтах і довжиною декодера в байтах.LELD

Тоді ваш рахунок - .A(LE+LD)

Перемога присуджується за подання найнижчим балом .

Термін

Існує дещо довільне обмеження часу в 1 хвилину на час виконання і Енкодера, і Декодера для однієї проби (тобто одного значення ).n

Мета полягає в тому, щоб уникнути рішення, яке знайде цю грубу силу кодування шляхом перерахування всіх послідовностей з певними властивостями. Якщо ваше рішення зробить щось більш розумне, ніж це, воно, швидше за все, відповідатиме часовим обмеженням і вважатиметься дійсним. Так само, якщо він працює на TIO для деяких випадково вибраних значень він вважатиметься дійсним. Інакше я перевіряю його на своїй машині, але зауважте, що якщо ваше рішення є чистою грубою силою, воно майже напевно вийде з ладу.n

Правила

  • Кодер і декодер повинні бути написані на одній мові .
  • Декодер необхідно виводити правильно ціле число для кожного з можливих перестановок з рядка , повернутого кодировщик .nss
  • Кодер і декодер є НЕ дозволяється обмінюватися інформацією будь-яким способом (наприклад , за допомогою глобальних змінних або файлів).
  • Вихід кодувальника повинен НЕ бути детермінованим (тобто, той же вхід може виробляти різні рядки виведення , якщо кодировщик виконується кілька разів), але Decoder завжди повинні вгадати правильне число .nnn
  • Кодер і декодер можуть приймати і повертати ціле число в будь-якому зручному способі (наприклад , якщо це нормально для введення , щоб бути , або ).nn = 14n=1414"14"[1,4]
  • Кодер може виводити рядок або шляхом друку його на або шляхом повернення рядка, список / масив символів або список / масив цілих чисел в діапазоні ; зауважте, що Декодер отримає як вхід перестановку , повернуту Енкодером , тому він повинен прийняти рядок у тому ж форматі, що і .s[ 0 , 127 ] s s sstdout [0,127]sss
  • Стандартні лазівки заборонені.
  • По можливості поясніть, як працює ваш код і чому оцінка, яку ви заявляєте, є правильною.

Приклад

Припустимо, .n=14

  • Кодер приймає в 14якості вхідних даних. Це може вивести "qwerty".
  • Декодер приймає перестановку в "qwerty"якості вхідних даних, наприклад "tweyqr". Він повинен виводити 14(у будь-якому зручному форматі).

Кодувальник міг би повернутися , [113,119,101,114,116,121]а також, в цьому випадку декодер отримав би (наприклад) [116,119,101,121,113,114].

Зауважте, що рядок, повернений Енкодером, може також містити символи ASCII, що не можна друкувати (але завжди в діапазоні [0x00, ..., 0x7F]).


Безумовно, довжина виводу не може бути нескінченною, ви не можете перетасувати нескінченну рядок
H.PWiz

@ H.PWiz Ні, це не може, але довжина може бути необмеженою, якщо Енкодер не детермінований
Delfad0r

"Енкодеру та декодеру заборонено обмінюватися інформацією жодним чином" Чи включають це допоміжні функції? тобто спеціальна функція, що обчислює N факторіал плюс три (випадковий приклад)
pizzapants184,

Чи може наш Енкодер повернути порожній рядок / список?
pizzapants184

2
@Kroppeb Так, станом на сьогодні правила говорять, що ви повинні рахувати байти двічі. Мені дуже цікаво бачити подання з двома однаковими програмами.
Delfad0r

Відповіді:


12

Желе , (17 байт + 18 байт) × довжина 6 = 210 балів

b36µỤỤ + × 3µŒ¿b3U + Ṣ
Ṣ: 3_J
Ṣ% 3Uḅ3œ? Çḅ36

Спробуйте в Інтернеті! (або з додатковою інформацією про налагодження)

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

Пояснення

Кодування

Першим кроком кодування є подання введення як бази 36 (b36 ). 36 6 = 2176782336> 2147483647, тому в результаті вийде не більше 6 цифр, кожна з яких знаходиться в діапазоні 0–35.

Далі ми перетворюємо це в представлення, яке містить 6, щоб додати оригінал до нового списку. Результат - представлення вхідного числа як шість різних цифр. Для цього існує декілька можливих алгоритмів, але один, який тут використовується, - це додати 1 до найменшої цифри, 2 до другої найменшої, 3 до третьої-найменшої тощо. Це означає, що якщо дві цифри були однаковими, одна з них буде довільно вважатися меншою, і таким чином вони стануть різними; і очевидно, що цей алгоритм не може змусити дві різні цифри стати однаковими. Щоб представити це в Jelly, ми використовуємо ("сортування індексів за значеннями") для отримання списку індексів у відсортованому порядку; ще раз перевернути це, ефективно відображаючи кожен елемент оригіналу у його положення у відсортованому порядку; іµ…+ різних цифр у діапазоні 1–41 (мінімум 0 + 1, максимум 35 + 6).

Потім ми розділити це на ще одну форму: в відсортоване список цифр в діапазоні 1-41, поряд з числом від 1 до 720 , який представляє , які з 720 можливих перестановок цифр були в (The. Œ¿І витягти кількість перестановок і упорядковано список відповідно.)

Нарешті, ми перетворюємо число від 1 до 720 в базу 3 ( b3), повертаємо його назад ( U) і кодуємо шість базових 3-х цифр і шість 1–41 цифр, упаковуючи їх в один символ ASCII, використовуючи зворотний дівмод (значення символ mod 3 є базовим 3-значним, значення, розділене на 3, становить 1–41 цифра). Можливий діапазон результатів (1 × 3) + 0 = 3 як мінімум, і (41 × 3) + 2 = 125 максимум, що відповідає нашому діапазону ASCII. Упаковка проводиться через ×3та +разом з додатковою, µщоб переконатися, що кожна команда працює на потрібному біті даних. (Тут є трішки гольф-хитрості, оскільки ми робимо множення на 3 раніше витягувати перестановку; це економить необхідність витратити байт на групувальний персонаж.)

Між іншим, причина зворотного номера базового 3 полягає в тому, що воно може мати менше цифр, ніж число 1–41. (Не може бути більше; найменше число, для якого n !> 3 n трохи вище 6.) Желе ефективно вставляє проміжні нулі, коли додає два числа різної довжини, щоб зрівняти їх; кінцеві нулі впливають на інтерпретацію числа, але провіднізворотні нулі не будуть, тому зворотний використовується для того, щоб зайві нулі опинилися десь, що не зіпсує нашу відповідь.

Розшифровка

Перший крок декодування - це витягнути два числа (базове 3 число та 1–41 число). Ми можемо отримати їхні цифри досить легко за допомогою поділу (:3 ) та модулем ( %3) відповідно, але як знати, в якому порядку вони були? Ну, число 1–41 мало свої цифри в упорядкованому порядку, а цифри у відповідних позиціях двох чисел зберігалися в одних і тих же символах; таким чином, ми можемо розібратися, в якому порядку розставляли цифри 1–41 числа (дивлячись на їх відносні значення), і знаємо, що цифри базового числа 3 повинні бути зміщені однаково. Насправді, оскільки символи кодування ASCII сортуються так само, як цифри 1–41 числа (всі вони були чіткими і вони більш значущі, ніж базові 3 числа),. Таким чином, обидві видобування починаються з наступних, а далі %3або :3за необхідності.

Хоча цифри 1–41 числа все ще перебувають у відсортованому порядку, у нас є дуже зручний / короткий спосіб повернутися до 0–35 цифр бази 36; просто відняти 1 від першого, 2 від другого, 3 від третього і так далі. У Jelly ми можемо це зробити за допомогою _J("віднімання індексу").

Тим часом, в іншій гілці декодування ми повертаємо цифри базового 3 числа назад у порядок ( U) і перетворюємо його з бази 3 назад в індекс перестановки з ḅ3.

Потім ми можемо поєднати дві гілки œ?Ç; œ?означає "перестановка з урахуванням цього індексу перестановки" і Çозначає "результат застосування рядка вище", тобто це те, що говорить Jelly запускати обидві лінії окремо на одному вході.

Зараз у нас є цифри оригінального числа, як в базовій 36 (внаслідок _J), так і в початковому порядку (завдяки œ?), тому ми можемо просто зробити ḅ36перетворення назад із бази 36 в єдине ціле число.

Коментар

ТІО! Посилання вище використовує 312699167 як номер для кодування. Це число в базі 36 є [5, 6, 6, 8, 7, 35]і, таким чином, показує всі аспекти кодування: 35 перевіряє границю діапазону 0–127, який ми маємо; дублікат 6s перевіряє роздільну здатність однакових цифр у вихідній базі 36; а той факт, що цифри майже (але не зовсім) відсортовані, означає, що номер перестановки дуже малий, що дає йому набагато менше цифр, ніж базове число 36, і, таким чином, показує необхідність змінити його перед додаванням до оригіналу.

Дійсно зручно, як всі константи тут вписуються. 36 6 лише достатньо високий, щоб вмістити 2 31 , 3 6 - лише достатньо високий, щоб вмістити 6!, А (36 + 6) × 3 лише достатньо високий, щоб вміститись у 128 можливостей. (Останнє обмеження тут є найменш жорстким, тому що ми можемо використовувати 0-індексацію, а не 1-індексацію, щоб використовувати символи в діапазоні 0-2. Все-таки це дало б достатньо місця для використання 37 як базової ніж 36.)


9

Желе , ( 4 3 байти + 6 5 байт) × довжина 8 = 80 64 бали

b⁴Ä
ṢŻIḅ⁴

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

Желе , ( 2 1 байт + 4 3 байти) × довжина 10 = 60 40 балів

Ä
ṢŻІ

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

Пояснення

Рішення 1

Для цього використовується інший алгоритм від більшості інших відповідей. Почнемо з кодування значення в шістнадцятковій ( b⁴), як і в інших відповідях, потім беремо кумулятивну суму ( Ä). Кожен вхід чітко дасть різний вихід (оскільки обидві ці операції є оборотними), і враховуючи, що шістнадцяткове кодування буде містити не більше 8 цифр, максимум яких становить 7 (для 8-ї останньої цифри) та 15 (для останньої до 7-ї- останні цифри), максимальне число у списку вихідних даних становитиме 7+ (7 × 15) = 112, менше 127, необхідних для запитання. Крім того, висновок обов'язково буде впорядкованому порядку, що дозволить нам змінити переміщення.

Для декодера спочатку повертаємо перетасовку сортуванням ( ); потім обернути кумулятивну суму, попередньо додавши нуль ( Ż) та взявши різницю послідовних пар ( I); потім перетворити назад із шістнадцяткової ( ḅ⁴).

Рішення 2

Питання насправді дозволяє нам сприймати дані як список (імовірно десяткових) цифр, тому ми можемо «обдурити», просто видаливши базову конверсію; максимальна кількість, що використовується у висновку, буде 2 + (9 × 9) = 83 (фактично 82, оскільки 2999999999 знаходиться поза діапазоном, тому найгірший можливий вхід - 1999999999). Отримане кодування є досить жахливим, оскільки кодування для цієї проблеми йде, але воно має перевагу в тому, що він генерується дуже коротко, що перевершує багатослівність кодування.

Ця відповідь настільки схожа на обман, що це не моє основне рішення цієї проблеми, але здається, що варто додати, оскільки це технічно відповідає правилам і дає кращу оцінку.

Коментар

Я маю на увазі кілька алгоритмів для отримання нижче довжини 8, але, мабуть, ви могли б реалізувати алгоритм довжиною 7 в ≤9 байт (не обман) або ≤5 байт (обман), тож, підрахувавши підсумки у питанні, це це, мабуть, найкращий спосіб зробити це. (Я, можливо, вирішувати альтернативну проблему "мінімізувати тривалість кодування", однак, просто для розваги.)

На відміну від деяких рішень, використання 16 як бази тут не є критичним; Є багато інших чисел, які працювали б для рішення довжини 8 (наприклад, 18). Я вибрав 16 для першого рішення просто тому, що в Jelly є 1-байтний спосіб представити це, а інші життєздатні бази повинні використовувати кілька байтів програми. Звичайно, для другого рішення необхідно використовувати 10 як основу для того, щоб використовувати лазівку.

Завдяки @Dennis за вказівку нових команд Jelly, які зробили цей алгоритм ще складнішим для запису.


3
Äкороткий для +\, Żкороткий для 0;.
Денніс

7

Мова програмування Шекспіра , 10 * (264 + 494) = 8650 7910 7580

Енкодер: 264 байт

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Be you nicer zero?You be the sum ofyou the product ofthe sum ofI a big big pig the sum ofa big big big big cat a big big pig.If soSpeak thy.Ford:You are the sum ofyou a cat.If soLet usAct I.

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

Дешифратор: 494

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Is you nicer a pig?If soRemember you.If soLet usAct I.Scene V:.Ford:Remember I.Ajax:Recall.Is you worse the sum ofPage twice the sum ofa big big cat a cat?If soYou be the difference betweenyou Page.If soOpen heart.If notlet usScene V.Scene X:.Ford:Recall.Ajax:Be I nicer zero?If soRemember I.If soLet usScene X.[Exit Ajax][Enter Page]Ford:You be the sum ofyou twice twice the sum ofa big big cat a pig.Let usAct I.

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

Це була річ.

Кодер кодує кожну цифру як цифру плюс індекс цифри разів дванадцять. Декодер зберігає весь вхід у пам'ять Форда, а потім петлює на лічильник, виводячи потім видаляючи кожну цифру нижче лічильника * 12 + 10.

Пояснення:

Енкодер

,.Ajax,.Ford,.Act I:.Scene I:.      Boilerplate introducing the two characters
[Exeunt][Enter Ajax and Ford]       Enter the two characters Ajax and Ford
                                    Ford will be handling the input
                                    Ajax will be the counter
Ajax:Open mind.                     Set Ford to the next character of input
Be you nicer zero?                  Check if it is EOF
You be the sum of                   Set Ford to the sum of 
    you                             His original value (48 to 58)
    the product of                 
          the sum of               
              I                     Ajax's value
              a big big pig         Minus 4 (this handles the offset of 48)
          the sum of                Multiplied by
              a big big big big cat 2^4
              a big big pig.        + -2^2 = 12
                                    This essentially sets Ford to (F+12*(A-4))
If soSpeak thy.                      If not EOF, print Ford's value
Ford:You are the sum ofyou a cat.   Increment Ajax's value
If soLet usAct I.                   If not EOF, Repeat again.

Дешифратор

,.Ajax,.Ford,.Page,.Act I:.Scene I:.  Boilerplate introducing three characters
                                      Ajax is the spare stack
                                      Ford is the storage stack
                                      Puck is the counter, increasing by 12
[Exeunt][Enter Ajax and Ford]            Enter Ajax and Ford onto the stage
Ajax:Open mind.                          Get the next character of input
Is you nicer a pig?                      If not EOF
If soRemember you.                         Store the value in Ford's memory
If soLet usAct I.                          And repeat the loop
Scene V:.                                Otherwise move to the next scene
Ford:Remember I.                         Store Ford's value (initially -1 from EOF) in Ajax's memory
Ajax:Recall.                             Get the next value from Ford's memory
Is you worse the sum of                  Is the value smaller than
        Puck                                  Puck's value
        twice the sum ofa big big cat a cat?  + 10 ?
                                              i.e. is it the next digit?
If soYou be the difference betweenyou Puck.   If so, subtract Puck's value from Ford
If soOpen heart.                              And print Ford's value
If notlet usScene V.                     If that was not the digit, repeat
Scene X:.
Ford:Recall.                             Get the next value from Ajax's memory
Ajax:Be I nicer zero?                    Until the -1
If soRemember I.                         Returning the values to Ford's memory
If soLet us Scene X.                     Repeat until Ajax's memory is exhausted
[Exit Ajax][Enter Page]                  Swap Ajax and Page
Ford:You be the sum of                   Set Puck's value to
              you                        Puck +   
              twice twice the sum of     2*2*(
                           a big big cat      4
                           a pig.             -1) = 12
Let usAct I.                             And start from the beginning again, having removed one number

5

Пітон 2,7, 31 * (52 + 37) = 2759

Енкодер ( 69 52 байти):

lambda n:[chr(i)if n&(1<<i)else""for i in range(32)]

Декодер ( 41 37 байт):

lambda s:sum([1<<(ord(c))for c in s])

Зберігає всі ненульові біти у вхідному числі у вигляді значень ascii. Значення символу ascii зберігає положення заданого біта. Наприклад, значення 'a' означає, що 97-й біт встановлений.

Кілька покращень, завдяки @ Delfad0r

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


Ласкаво просимо до PPGC! Ви можете скинути e = і d = на початку - анонімні функції ідеально чудово. Також зауважте, що в заяві проблеми чітко сказано, що Кодер може повертати список цілих чисел замість символів, тому ви можете уникнути цілочисельного перетворення цілого числа> символ->. Більше того, ви можете використовувати n&(1<<i)замість n&(1<<i)>0і зберегти 2 байти. Нарешті, верхня межа для i(127) є занадто великою, 32 є достатньою, і економить 1 байт.
Delfad0r

1
Будь ласка, вкажіть свій бал згідно з розділом « Підрахунок балів» у заяві про проблему.
Delfad0r

@ Delfad0r Чи правильно нарахування балів зараз? І дякую за поради.
Хайн Весселс

Я думаю, що бал є (52+37)*31=2759тим, що найдовше, коли встановлено всі 31 біт.
Джонатан Аллан

Енкодером можна lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]зберегти 6 байт.
mypetlion

5

Стакс , оцінка 8 × (10 + 9) = 152

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

Ç·MÉJ'♀τ│½

Запустіть і налагоджуйте його

16|E{i16*+m Full program, implicit input
16|E        Get hexadecimal digits
    {     m Map:
     i16*+    Add 16 * loop index
            Implicit output as string

Кодер виводить рядок у порядку зростання.

Декодер, 9 байт

üL∟n╫k∞‼9

Запустіть і налагоджуйте його

o{16%m16|E Full program, implicit input
o          Sort string
 {16%m     Module each element by 16
      16|E Interpret as array of hex digits


5

Пітон 3 , 8 * (45 + 38) = 664

Енкодер (45 байт):

lambda n:[16*i+(n>>4*i)%16 for i in range(8)]

Декодер (38 байт):

lambda l:sum(x%16<<x//16*4 for x in l)

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


1
Ви можете видалити пробіли перед "за", lambda l:sum(x%16<<x//16*4for x in l)працює чудово :)
FatalError

4
Це не працює. Вихід не є простим ASCII (в діапазоні 0..127)
GB

2
@GB моя помилка. Я порушив це з останньою редакцією. Повернення зараз
Кертіс Бехтел,

збережіть у кодері 3 байти: lambda n:[n>>4*i&15|i<<4for i in range(8)]і 1 в декодері: lambda l:sum(x%16<<x//16*4for x in l)за загальний бал 632
Аарон

4

JavaScript (ES6), 8 * (40 + 32) = 576

08

Енкодер (40 байт)

E=(n,k=0)=>n?[k|n&15,...E(n>>4,k+16)]:[]

Декодер (32 байти)

s=>s.map(c=>s|=c%16<<(c/4&~3))|s

Демо

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

Як?

Вхід розділений на 8 блоків по 4 біти, і кожен блок кодується 1 серед 16 можливих символів. Найбільш значущий біт останнього блоку ніколи не встановлюється.

       3222222222211111111110000000000
bit:   0987654321098765432109876543210
       \_/\__/\__/\__/\__/\__/\__/\__/
block:  7  6   5   4   3   2   1   0

block #0 is encoded with char. 00 to 0F (NUL to SI)
block #1 is encoded with char. 10 to 1F (DLE to ES)
block #2 is encoded with char. 20 to 2F (' ' to '/')
block #3 is encoded with char. 30 to 3F ('0' to '?')
block #4 is encoded with char. 40 to 4F ('@' to 'O')
block #5 is encoded with char. 50 to 5F ('P' to '_')
block #6 is encoded with char. 60 to 6F ('`' to 'o')
block #7 is encoded with char. 70 to 77 ('p' to 'w')

4

Желе , (8 + 9) байт * 8 макс-довжина = 136

b⁴+J’Ɗ⁴¡

Енкодер (нижній колонтитул форматує список так, як Python би для наочності)

Ṣ_J‘Ɗ⁴¡ḅ⁴

Дешифратор

Теоретично можливо мати максимальну довжину шість, це може бути зроблено в 22 байти або менше?

i=0i=5(127+i127)=321402081<2311

Як?

23117fffffff[7,15,15,15,15,15,15,15][7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]

Кодер :

b⁴+J’Ɗ⁴¡ - Link: integer, n    e.g. 1234
 ⁴       - literal 16               16          
b        - convert to base          [4,13,2]
       ¡ - repeat...
      ⁴  - ...16 times:
     Ɗ   -   last 3 links as a monad:
   J     -     range of length        [1,2,3]     iter 2    iter 3    ...  iter 16
  +      -     add                    [5,15,5]   [5,16,7]   [5,17,9]  ...  [5,30,35]
    ’    -     decrement              [4,14,4]   [4,15,6]   [4,16,8]  ...  [4,29,34]
         -                                                                 [4,29,34]

Декодер :

Ṣ_J‘Ɗ⁴¡ḅ⁴ - Link: list of integers   e.g. [29,34,4]
Ṣ         - sort                          [4,29,34]
      ¡   - repeat...
     ⁴    - ...16 times:
    Ɗ     -   last 3 links as a monad:
  J       -     range of length           [1,2,3]
 _        -     subtract                  [3,27,31]   [3,26,29]   [3,25,27]  ...  [3,12,1]
   ‘      -     increment                 [4,28,32]   [4,27,30]   [4,26,28]  ...  [4,13,2] 
        ⁴ - literal 16                    16
       ḅ  - from base                     1234

"шістнадцяткові цифри", звичайно. ("цифри, що використовують звичайний шістнадцятковий", довше, а лише "цифри" мають на увазі десяткові.)
Ерік Аутгольфер

Я змінив це, хоча це повинно було бути очевидно з контексту, оскільки я одразу ж посилався на шістнадцяткові цифри.
Джонатан Аллан

Ваш розрахунок вичерпано одним: є 321402081 комбінації із заміною максимальною довжиною 5 та 7177979809 з максимальною довжиною 6.
Anders Kaseorg

@AndersKaseorg ой, так це - так можна з максимальною довжиною 6 ... даючи 22 байти, щоб грати!
Джонатан Аллан

4

Мова програмування Шекспіра , 31 * (472 + 383 379 344) = 26505 26381 25296

Попередня оцінка: 16909322 * (246 + 217) = 7829016086

Це все ще дуже високо, але це найнижчий рівень, про який я зараз можу подумати.

Кодер:

,.Ajax,.Ford,.Act I:.Scene I:.[Enter Ajax and Ford]Ajax:Remember a pig.Ford:Listen tothy.Scene V:.Ajax:Remember the remainder of the quotient betweenI a big cat.Ford:You be the quotient betweenyou a big cat.Be you nicer zero?If solet usScene V.Remember a pig.Scene X:.Ajax:Recall.Ford:Am I worse zero?If notremember I.If notlet usScene X.Ajax:You zero.Scene L:.Ford:Recall.Ajax:You be the sum ofyou a cat.Am I nicer zero?If sospeak thy.Am I worse zero?If notlet usScene L.

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

Декодер:

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You cat.Ford:Open mind.Remember the sum ofyou I.Scene V:.Ajax:Am I nicer a cat?If soyou be twice you.Ford:If soyou be the sum ofyou a pig.If solet usScene V.[Exit Ford][Enter Page]Page:Recall.Ajax:Am I worse a cat?If notyou be the sum ofyou Ford.If notlet usAct I.Open heart

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

В основному, якщо рядок містить символ з кодом ASCII (n + 1), встановлюється n-та двійкова цифра.


344 байти для декодера
Джо Кінг

3

Python 3, (208 байт + 200 байт) * 6 довжина = 2448

Спробуйте в Інтернеті! (містить обидва, додатковий байт - це новий рядок між ними).

-4 байти (-24 бали), використовуючи порожній список (який дозволив почати більше речей з 0)

Енкодер (208 байт)

def E(n,h=128):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    d=l=0
    s=[]
    while n>=T(h,d):
        n-=T(h,d)
        d+=1
    for i in range(d):
        while n>=T(h-l,d+~i):
            n-=T(h-l,d+~i)
            l+=1
        s+=[l]
    return s

Декодер (200 байт)

def D(s):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    s.sort()
    l=0
    d=len(s)
    n=sum(T(128,D)for D in range(d))
    for i in s:
        for j in range(l,i):
            n+=T(128-j,d-1)
        l=i
        d-=1
    return n

Спостереження:

  • Перемішування може бути втрачено без втрат для строго не збільшуваних (тобто відсортованих) списків.

  • Суворо незростаючі числові списки однакової довжини можна повністю упорядкувати (як вони є в Python).

  • Ми можемо визначити, що списки упорядковуються спочатку за довжиною, щоб сформувати загальний порядок усіх відсортованих списків.

  • Ми можемо сформувати індексованих послідовність цих списків , якщо ми визначимо , що тільки справжні значення в списку є цілими числами від 0до 127включно (тобто існує кінцеве число дійсних списків з довжиною L).

Стратегія:

  • Енкодер: Давши число N, знайдіть цей Nдійсний суворо незростаючий список.

  • Декодер: Давши (перетасований) дійсний список, сортуйте його та поверніть його індекс у послідовності дійсних списків.

Поширене пояснення коду:

  • T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1

  • Обчислити nй dсимплекс номер

    • Для d=0 завжди1

    • Для d=1, n(кількість точок у рядку крапок з довжиною n)

    • d=2i=1nin

    • d=3j=1ni=1jin

Пояснення кодера:

  • def E(n,h=128): d=l=0, s=[]

  • n- це вхідне число, h"високе значення" (тобто найбільше дозволене число + 1), dце довжина, якою буде вихід, sє вихід, l"низьке значення" (починаючи з 0, пояснюється далі пізніше)

  • while n>=T(h,d):, n-=T(h,d),d+=1

  • Є T(h,d)дійсні dсписки довжин , і наш розрахунок простіше, якщо nіндекс відносно списку [0]*d(в індексі 0) замість фактичного індексу, тому зменшення nвідповідно. Це також коригує d(довжину), щоб бути правильним для даної n.

  • for i in range(d):

  • Ефективно: "для i+1першого числа у списку"

    • Тут я поясню l , "низьке значення"

    • Після того, як число було внесено до списку, не менше його можна буде внести до списку (щоб його було відсортовано), так l є і останнє число, яке було додано до списку.

    • while n>=T(h-l,d+~i):, n-=T(h-l,d+~i),i+=1

    • Якщо nвона занадто велика, щоб бути закодованою з lцією "цифрою", то відрегулюйте nвідповідно і збільшенняl

    • s+=[l]

    • Кодуйте nза допомогою lцієї "цифри".

    • Спочатку у нас є hваріанти того, яку "цифру" потрібно поставити наступною, але як тільки ми вводимо "цифру" (яка призначена l), ми обмежуємось h-lваріантами для наступної "цифри".

    • Спочатку були T(h,d)дійсні списки, але ми додали "цифру" l, зменшуючи кількість залишених "цифр" d-1та кількість дійсних наступних "цифр" до h-l, тому кількість дійсних списків після цьогоT(h-l,d-1)

Пояснення декодера:

  • def D(s):, s.sort(), l=0,d=len(s)

  • sперелік вхідних даних (перетасований), так s.sort()це; lє "низьке значення" ( h"високе значення" - це просто буквальний 128s у коді для збереження байтів), nце вихідний номер, dце довжина.

  • n=sum(T(128,D)for D in range(d))

  • Відрегулюйте nточку в послідовності[0]*length

  • for i in s:

  • Для кожної цифри:

    • for j in range(l,i):, n+=T(128-j,d-1)

    • Відрегулюйте nточку в послідовності[...prevdigits, thisdigit, 0...]

      • l=i: Встановіть "низьке значення" на останню цифру

      • d-=1: Зменшення довжини, оскільки ми використовували цифру

  • return n: Після nкоригування для всіх цифр це правильне число; поверніть його.

Вибачте, якщо це не зрозуміло, але ось моя оригінальна версія для налагодження без вогків Спробуйте в Інтернеті! , який не використовує порожній список, тому 1 раз від усіх номерів, використовуваних у цій версії


3

Рубі , (36 + 29 байт) * 8, оцінка 520

Кодування:

->n{(0..7).map{|x|(n>>x*=4)%16+x*4}}

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

Розшифруйте:

->a{a.sum{|x|x%16<<(x/4&28)}}

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

Як це працює:

Число кодується за допомогою 4-бітних фрагментів та 3-бітного індексу.

Декодер приймає вхідний масив і знову ставить кожен кусок на своє місце.


3

Вугілля , оцінка 10 * (10 + 15) = 250.

Використовує десяткові; попереднє базове рішення на основі 16 набрало 328 296 264.

Може виводити символи, що не друкуються. Зокрема, персонаж 10 є складним для введення у вугілля.

Енкодер, 10 байт:

⭆⮌S℅⁺Iι×χκ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду.

Декодер, 15 байт:

IΣES×﹪℅ιχXχ÷℅ιχ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду.

Версія з використанням списку цілих чисел 360 296 (основна 16; десятковий - 310):

Енкодер, 19 байт:

NθIE⁸⁺﹪÷θX¹⁶ι¹⁶×¹⁶ι

Спробуйте в Інтернеті! Посилання на багатослівну версію коду.

Декодер, 18 байт:

IΣEE⁸N×﹪ι¹⁶X¹⁶÷ι¹⁶

Спробуйте в Інтернеті! Посилання на багатослівну версію коду.

Версія з використанням 360 символів для друку (становила 416 384 368 в базі 16):

Енкодер, 19 байт:

⭆⮌S℅⁺Iι×χ⁺κ×⁵⊕׳÷κ⁵

Спробуйте в Інтернеті! Посилання на багатослівну версію коду.

Декодер, 17 байт:

Fθ⊞υ⌈Φθ¬№υκ⭆υ﹪℅ιχ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду.


2

Брахілог , 17 + 18 байт * 8 довжина = 280

Кодер:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐ

Декодер:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐp

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

Якщо буде (правильно реалізована) сукупна сума предиката, оцінка може знизитися до 20

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


@ Delfad0r додавання p до кодера зробить це тим самим кодом для кодування та декодування
Kroppeb

2

05AB1E , оцінка: (2 + 2 байти ) * 11 максимальна довжина = 44

Кодер (2 байти ):

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

Декодер (2 байти ):

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

Введення кодера і вихід декодера - це список цифр.

Порт @ ais523 «сек другий Jelly відповідь .

Пояснення:

    # Undelta (automatically prepends a 0)
      #  i.e. [3,0,4,7,8,2,0,1,9] → [0,3,3,7,14,22,24,24,25,34]

{     # Sort
      #  i.e. [14,7,22,25,24,3,0,24,34,3] → [0,3,3,7,14,22,24,24,25,34]
 ¥    # Deltas
      #  i.e. [0,3,3,7,14,22,24,24,25,34] → [3,0,4,7,8,2,0,1,9]

2311


2

Гол> <> , 8 * (14 + 13) = 216

Encoder Спробуйте в Інтернеті! , 14 байт:

I8FfPSD8*L+o|;

Декодер Спробуйте в Інтернеті! , 13 байт:

iEh8SD4*2$X*+

Оскільки це може виводити недруковані символи ascii, таким чином, возитися з декодером, тепер є версія, що використовує цифри у виводі / вході:

Encoder Спробуйте в Інтернеті! , 14 байт:

I8FfPSD8*L+N|;

Декодер Спробуйте в Інтернеті! , 13 байт:

IEh8SD4*2$X*+

Кодування:

Кодування працює, розбиваючи задане число на 8 х 4 бітні шматки. Потім ці шматки зміщуються вправо на 3 біти, а вихідне місце відрізка додається на кінці як число між 0 і 7. Таким чином, кодування виглядає так:

0AAAABBB
 |__|    -> the original part of the number
     |_| -> the position of the chunk inside the original number 0 = LSB and 7 = MSB

2

Perl 6 , 10 * (10 + 12) = 340 220

Кодер:

{^@_ Z~@_}

Декодер:

{.sort X%10}

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

Функція кодера переміщує кожну цифру з 0-індексом числа. Потім кодер сортує список чисел і отримує модуль на 10, іншими словами другий розряд числа.

Всього 10, оскільки це максимальна довжина 2 31 -1.


1

Haskell , 10 * (23 + 51) = 740

Ось програма, що кодує, перетасовує, розшифровує та перевіряє значення: Спробуйте це в Інтернеті!

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

zipWith((+).(10*))[0..]

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

Дешифратор, 51 байт

map snd.sortOn fst.map(`divMod`10)
import Data.List

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

Пояснення

Оскільки нам дозволяється використовувати введення в якості десяткових цифр, ми будемо використовувати це .. Кодер відображає кожну цифру, що виникає 10*index + digit, зауважимо, що всі digits будуть у [0..9]тому, щоб ми могли перетворити вищезазначене, використовуючи divMod. Після відновлення індексів та цифр залишається лише сортувати за індексами та позбуватися від них.

2311=214748364799=81<128



1

LE+LD=36;A=8288

d←{16n-16×⍳≢n←⍵[⍋⍵]}
e←(⊢+16×⍳∘≢)16⊥⍣¯1

Спробуйте в Інтернеті! (містить 5 додаткових байт для завдань та новий рядок).

Використання ⎕IO←0

Як:

(⊢+16×⍳∘≢)16⊥⍣¯1  Encoder; input 1234
          16⊥⍣¯1  Convert input to base 16  4 13 2
      ⍳∘≢           [0..length of the list-1]  0 1 2
   16×              times 16  0 16 32
 ⊢+                 plus the original list  4 29 34

{16n-16×⍳≢n←⍵[⍋⍵]}  Decoder; input   34 4 29
              [⍋⍵]   Grade  up  2 0 1
                    Index  with that list  4 29 34
           n        assign that to n
      16×⍳≢          16×[0..length(n)-1]  0 16 32
    n-               subtract that from n  4 13 2
 16                 Decode from base 16  1234

1

PHP, 8 * (44 + 53) = 776

кодер, 44 байти:

for(;$n=&$argn;$n>>=4)echo$n&15|16*$i++," ";

друкує розділений пробілом список цілих чисел. Запустити як труба -nR.

максимум 8 байтів з 4 бітами даних (нижня куля) і 3 ваговими бітами (верхня куля).

Простіше кажучи:
покладіть кожну шістнадцяткову цифру у власний символ і використовуйте верхню половину байта для зберігання позиції цифри.

приклад:

1457893891( 0x56e5b203) Чи перетвориться в
0x03, 0x10, 0x22, 0x3b, 0x45, 0x5e, 0x66, 0x75
3 16 34 59 69 94 102 117

декодер, 53 байти:

while($i++<8)$n+=(15&$x=$argv[$i])<<($x>>4)*4;echo$n;

або

while($i++<8)$n+=(15&$x=$argv[$i])<<($x/4&~3);echo$n;

або

for(;$i<9;$x=$argv[++$i])$n+=$x%16<<($x/4&~3);echo$n;

взяти цілі числа з аргументів командного рядка. Бігайте з -nr.


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


0

Пітон 2 , 10 * (68 + 54) = 1220

e=lambda n:"".join(chr(int(`i`+j))for i,j in enumerate(`n`)if j<'L')
d=lambda s:int("".join(`ord(c)%10`for c in sorted(s)))

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

EDIT: Спасибі Джо Кінгу за покажчики - не впевнений, чому я зарахував 32, заднім числом.

Кодує позицію та значення кожного місця як єдиного символу, починаючи з [пробіл] (позиція 0, значення 0) байт NUL 0x0.

Розшифровує:

  • сортування рядка (Python буде сортувати символи за порядковим значенням)
  • перетворює кожен символ у його порядкове значення
  • приймає останню цифру кожного порядкового цілого числа
  • з'єднує цілі числа в рядок
  • перетворює об'єднаний рядок назад у int

Вам потрібен 32залік? Крім того, [-1]міг бути %10натомість у потрібному місці
Джо Кінг,

0

C (gcc) , 10 * 112 = 1120

c,i;e(i,s)char*s;{for(c=1;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=--c%10*pow(10,c/10));s=i;}

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

У мене є глобальні змінні, але вони фактично не передають інформацію між двома функціями. Змінна декларація для cвикористовується в обох функціях, зберігаючи мені 2 байти в довжині коду.

Тут доступна версія, яка використовує ASCII для друку лише для штрафу 3 5 байт:

c,i;e(i,s)char*s;{for(c=32;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=(c-=32)%10*pow(10,c/10));s=i;}

Дякуємо @ceilingcat за 70 вдосконалень.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.