Давайте зробимо кілька "enciph5r47g"


35

Це зворотне значення Давайте зробимо кілька "deciph4r4ng"


У цьому виклику ваше завдання полягає в шифруванні рядка. На щастя, алгоритм досить простий: читання зліва направо, кожен типовий символ запису (діапазон ASCII 32-126) повинен бути замінений цифрою N (0-9), щоб вказати, що він такий самий, як символ N + 1 позиції перед нею. Виняток становить, коли символ не відображається в попередніх 10 позиціях у початковому рядку. У такому випадку вам слід просто надрукувати символ ще раз. Ефективно, ви повинні мати можливість скасувати операцію від початкового завдання.

Приклад

Рядок введення "Programming"буде закодований таким чином:

Example1

Отже, очікуваний вихід "Prog2am0in6".

Роз'яснення та правила

  • Вхідний рядок буде містити символи ASCII виключно в діапазоні 32 - 126. Можна припустити, що він ніколи не буде порожнім.
  • Оригінальний рядок гарантовано не містить жодної цифри.
  • Після того, як персонаж був закодований, він може в свою чергу посилатися на наступну цифру. Наприклад, "alpaca"має бути закодовано як "alp2c1".
  • Посилання ніколи не обертаються навколо рядка: на нього можуть посилатися лише попередні символи.
  • Ви можете написати або повну програму, або функцію, яка або друкує, або виводить результат.
  • Це кодовий гольф, тому найкоротша відповідь у байтах виграє.
  • Стандартні лазівки заборонені.

Тестові справи

Input : abcd
Output: abcd

Input : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

Input : golfing is good for you
Output: golfin5 3s24o0d4f3r3y3u

Input : Programming Puzzles & Code Golf
Output: Prog2am0in6 Puz0les7&1Cod74G4lf

Input : Replicants are like any other machine. They're either a benefit or a hazard.
Output: Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.

6
Я бачу, що у ваших тестових випадках завжди використовується найменша цифра, яка можлива для будь-якої заміни. Це потрібна поведінка, чи ми можемо використовувати і більш високі цифри, коли існує більше ніж одна можливість?
— Лев

@Leo Ви можете використовувати будь-яку однозначну цифру, яку потрібно 0-9, доки вона дійсна.
— Інженер Тост

Це як кодер, що рухається вперед , за винятком без рухомого :)
— труба

Відповіді:


6

05AB1E , 20 19 18 байт

-2 Завдяки Еміньї

õ¹vDyåiDykëy}?yìT£

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

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S

Я думаю, що )¹vDyåiDykëy}?y¸ìT£працює також.
— Емінья

Власне, поєднання вашої відповіді з моєю дає õIvDyåiDykëy}?yìT£за 18 :)
— Емінья

@Emigna Не соромтеся оновити своє з цим :)
— Райлі

Я б не подумав про це, якби не ваша відповідь, тож ви повинні її мати. Хороша робота!
— Емінья

@Emigna Я думаю, це справедливо. Спасибі!
— Райлі

12

Сітківка , 24 23 байти

(.)(?<=\1(.{0,9}).)
$.2

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

Досить просте заміщення регулярних виразів. Ми підбираємо кожен символ і намагаємось знайти його копію 0-9 символів перед ним. Якщо ми його знайдемо, ми замінимо символ на кількість символів, з якими нам довелося відповідати, щоб дістатись до копії.

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


4
Обмін змінної довжини обманюється: p
— Дада

8
@Dada Перегляд змінної довжини - це шлях до просвітлення.
— Мартін Ендер

На жаль це ... Якщо вам нудно, сміливо впроваджуйте їх всередині Perl!
— Дада

Відповідно до коментаря ОП до оригінального завдання, "Ви можете використовувати будь-яку одну цифру, яку ви хочете, 0-9, поки це дійсно." ... Настільки великий можливий повинен бути дійсним
— Doktor J

@DoktorJ так, я змінив його після того, як ОП додав уточнення.
— Мартін Ендер

8

JavaScript (ES6), 74 57 54 байт

Збережено 3 байти завдяки ETHproductions з блискучим p=/./g замість p={}(натхненним Нілом)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

Тестові справи


Оскільки рядок гарантовано не містить цифри, ви можете використовувати sзамість p?
— Ніл

(Мені вдалося перевершити вашу оригінальну findверсію за допомогою lastIndexOf, що трохи дивно, враховуючи, що це 11 літер…)
— Ніл

@Neil Я зараз не перед комп'ютером, але я не думаю, що це спрацює, оскільки струни JS незмінні.
— Арнольд

2
Я можу підтвердити, що налаштування властивостей для рядкових літералів не працює. Але ... схоже, це працює з регулярним виразом, тому я думаю, що ви могли б зробити, s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)щоб зберегти 3 байти.
— ETHproductions

1
@YOU Я насправді не знаю, що тут сталося, але виявляється, що я вніс помилку для всіх браузерів під час останньої редагування. Це зараз виправлено. Дякуємо, що помітили!
— Арнольд

7

Haskell , 72 66 байт

Дякуємо Лайконі за те, що грає в 6 байт!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

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

Функція %зберігає частково оброблювану рядок у зворотному значенні у своєму другому аргументі, тому вона може шукати перші 10 елементів цього рядка для виникнення характеру, який він вивчає. Подання складається з безіменної функції, (%"")яка викликає попередню функцію порожнім рядком як другий аргумент.


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])економить два байти.
— Лайконі

Зачекайте, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]економить ще більше.
— Лайконі

Повернення на ході замість використання reverseекономить ще один байт: Спробуйте це в Інтернеті!
— Лайконі

@Laikoni Дякую, це чудово!
— Лев


3

Perl 5 , 36 байт

35 байт коду + -pпрапор.

s/(\D)(.{0,9})\K\1/length$2/e&&redo

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

Деякі пояснення:
мета - замінити нецифровий символ ( \Dале він відповідає зворотному посиланню \1в моєму регулярному виразі), якому передує менше 10 символів (.{0,9} ) і того ж символу ( (\D)... \1) за довжиною .{0,9}групи ( length$2). І redoпоки персонажі замінюються.


мабуть, .*це не потрібно, будь-яка дійсна таблиця в діапазоні до заміненої цифри в порядку.
— colsw

@ConnorLSW Так, я щойно побачив це оновлення виклику і змінив свою відповідь, дякую, що вказав на це.
— Дада


3

Japt , 18 байт

£¯Y w bX s r"..+"X

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

Пояснення

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression


2

05AB1E , 20 байт

õIv¹N£RT£©yåi®ykëy}J

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

Пояснення

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string


2

C (tcc) , 113 байт

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

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

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

Редагувати

-15 байт. Спасибі Йохан дю Тойт .


Ага! Обмежте вхід до 98 символів і заощадите собі байт!
— труба

Приємне рішення, але ви можете зберегти ще 15 байт: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
— Йохан дю Тоїт

@JohanduToit Дякую! У мене одне питання. Як саме s [i] працює як умова циклу for? Я багато разів бачив це у відповідях інших людей на цьому веб-сайті.
— Максим Михайлов

@Max Lawnboy Спочатку у вас було таке: 's [i] ^' \ 0 '', яке скорочення для 's [i]! =' \ 0 ''. Буквал символів '\ 0' дорівнює нулю, тому ви можете записати його так: 's [i]! = 0'. Оператор if у C перевіряється лише у тому випадку, якщо значення оцінюється до нуля або не дорівнює нулю, тому значення "! = 0" не є необхідним.
— Йохан дю Тойт


2

Java 7, 102 101 байт

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

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

-1 байт завдяки Kevin Cruijssen . Мені завжди подобається використовувати привід перейти до оператора.


Чому --c>=0? Ви можете замінити його, c-->0щоб зберегти байт.
— Кевін Кройсейсен

@KevinCruijssen Я якось мав це в голові, що мені потрібно попередньо визначити, інакше власне обчислення буде неправильним ... Хороший улов!
— Пукайте

1

MATL, 31 30 байт

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

Спробуйте в MATL Online!

Пояснення

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display

Ви могли б бути трохи геть , але я дуже не можу сказати , де. Вхід this is a testвиходить this 222a1te52замість this 222a19e52. Другий tне перетворюється на 9.
— Інженер Тост

@EngineerToast Ха-ха, дякую. Я погляну.
— Suever

1

PHP, 104 байт

вперед рішення

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

Рішення назад

Інтернет-версії

PHP, 111 байт

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP, 112 байт

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

Інтернет-версія


1

REXX, 124 125 байт

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b

Ви можете трохи відмовитися. Я не знаю REXX, але я припускаю, що помилка знаходиться в рядку 7, де вона має s<9замість s<10або s<=9. Вхід this is a testотримує this 222a1te52замість this 222a19e52. Другий tне перетворюється на 9. Спробуйте в Інтернеті
— Інженер Тост

Дякую, це була дурна спроба поголити один байт. Код виправлено.
— idrougge

1

C (gcc) , 117 103 байт

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

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

103 байти без імпорту string.h, працює без попередження. Якщо це суперечить правилам, я його потягну

Гарний код:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

Зміни:

  • Змінено з LLVM на gcc, щоб дозволити неявне i, j оголошення, видалений імпорт lib.
  • Додано функціональну обгортку для відповідності

Запропонувати (i=strlen(s);s[--i];)замість(i=strlen(s)-1;s[i];i--)
— roofcat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.