Давайте сделаем немного «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£работает также.
Emigna
На самом деле, сочетание вашего ответа с моим дает õIvDyåiDykëy}?yìT£за 18 :)
Emigna
@Emigna Не стесняйтесь обновлять свой с этим :)
Riley
Я бы не подумал об этом, если бы не ваш ответ, поэтому вы должны иметь его. Отличная работа!
Emigna
@ Emigna Я думаю, это справедливо. Благодарность!
Райли
12

Сетчатка , 24 23 байта

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

Попробуйте онлайн!

Довольно простая замена регулярных выражений. Мы подбираем каждый символ и пытаемся найти его копию за 0-9 символов до него. Если мы его найдем, мы заменим символ на количество символов, которое нам нужно было сопоставить, чтобы получить копию.

Результаты не совсем соответствуют тестовым примерам, поскольку в этом случае используется наименьшая возможная цифра, а не наименьшая.

Мартин Эндер
источник
4
Смотритель изменчивой длины обманывает: p
Dada
8
@ Дада Переменная длина - путь просветления.
Мартин Эндер
К сожалению, это ... Если вам скучно, не стесняйтесь внедрять их в Perl!
Дада
В соответствии с комментарием OP на исходной задаче, «Вы можете использовать одну цифру , которую 0-9 до тех пор , как она действует.» ... так что максимально возможное должно быть действительным
Doktor J
@DoktorJ да, я изменил его после того, как ОП добавил это разъяснение.
Мартин Эндер
8

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

Сохранено 3 байта благодаря продуктам ETH с бриллиантом p=/./gвместо p={}(вдохновленный Нилом)

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

Контрольные примеры

Arnauld
источник
Поскольку строка гарантированно не содержит цифры, вы можете использовать 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

Python 2, 89 84 байта

m=input()[::-1];j=1;t=''
for i in m:s=m[j:].find(i);t=[i,`s`][0<s<10]+t;j+=1
print t

Попробуйте онлайн!

Перебирает всю строку в обратном порядке и создает новую строку с вставленными правильными числами.

математик наркоман
источник
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
ETHproductions
источник
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
Emigna
источник
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 байт. Спасибо Йохан дю Туа .

Максим Михайлов
источник
Agh! Ограничьте ввод до 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;}
Johan du Toit
@JohanduToit Спасибо! У меня есть один вопрос. Как именно s [i] работает как условие цикла for? Я видел это много раз в ответах других людей на этом сайте.
Максим Михайлов
@ Макс Лоунбой. Первоначально у вас было следующее: 's [i] ^' \ 0 '' - сокращение от 's [i]! =' \ 0 ''. Символьный литерал '\ 0' равен нулю, поэтому вы можете написать его так: 's [i]! = 0'. Оператор if в C только проверяет, имеет ли значение нулевое или ненулевое значение, поэтому «! = 0» не требуется.
Йохан дю Туа
100 байт
потолочный кот
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 байт благодаря Кевину Круйссену . Мне всегда нравится предлог, чтобы использовать оператор go-to.

совать
источник
Почему то --c>=0? Вы можете заменить его, c-->0чтобы сохранить байт.
Кевин Круйссен
@KevinCruijssen У меня почему-то было в голове то, что мне нужно было предварительно определить, иначе фактическое вычисление было бы неправильным ... Отличный улов!
Poke
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
Suever
источник
Вы могли бы быть немного прочь , но я очень не могу сказать , где. Ввод 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
idrougge
источник
Вы можете быть немного не в себе. Я не знаю 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--)
floorcat