Давайте сделаем немного «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)

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


Поскольку строка гарантированно не содержит цифры, вы можете использовать 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 байт. Спасибо Йохан дю Туа .


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» не требуется.
— Йохан дю Туа


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

Вы могли бы быть немного прочь , но я очень не могу сказать , где. Ввод 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--)
— floorcat
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.