Vamos fazer um "enciph5r47g"

35

Este é o inverso de Vamos fazer um "deciph4r4ng"


Nesse desafio, sua tarefa é codificar uma sequência. Felizmente, o algoritmo é bastante simples: lendo da esquerda para a direita, cada caractere de escrita típico (intervalo ASCII 32-126) deve ser substituído por um número N (0-9) para indicar que é o mesmo que o caractere N + 1 posições antes dele. A exceção é quando o caractere não aparece nas 10 posições anteriores na sequência original. Nesse caso, você deve simplesmente imprimir o caractere novamente. Efetivamente, você poderá reverter a operação do desafio original.

Exemplo

A string de entrada "Programming"seria codificada desta maneira:

Exemplo 1

Portanto, a saída esperada é "Prog2am0in6".

Esclarecimentos e regras

  • A sequência de entrada conterá caracteres ASCII exclusivamente no intervalo 32 - 126. Você pode assumir que nunca estará vazio.
  • A sequência original é garantida para não conter nenhum dígito.
  • Uma vez codificado, um caractere pode ser referenciado por um dígito subsequente. Por exemplo, "alpaca"deve ser codificado como "alp2c1".
  • As referências nunca serão agrupadas em torno da string: somente caracteres anteriores podem ser referenciados.
  • Você pode gravar um programa completo ou uma função que imprima ou produz o resultado.
  • Isso é código de golfe, então a resposta mais curta em bytes vence.
  • As brechas padrão são proibidas.

Casos de teste

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.
Engenheiro Toast
fonte
6
Vejo que seus casos de teste sempre usam o dígito mais baixo possível para qualquer substituição. Esse comportamento é obrigatório ou também podemos usar dígitos mais altos quando há mais de uma possibilidade?
Leo
@ Leo Você pode usar qualquer dígito que desejar de 0 a 9, desde que seja válido.
Engenheiro brinde
Isto é como um movimento para frente codificador, exceto sem o movimento :)
tubo de

Respostas:

6

05AB1E , 20 19 18 bytes

-2 Obrigado a Emigna

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

Experimente online!

õ                  # 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
Riley
fonte
Eu acho que )¹vDyåiDykëy}?y¸ìT£funciona também.
Emigna
Na verdade, combinando a sua resposta com o meu dá õIvDyåiDykëy}?yìT£para 18 :)
Emigna
@Emigna Sinta-se livre para a sua atualização com que :)
Riley
Eu não teria pensado nisso se não fosse a sua resposta, então você deveria. Bom trabalho!
Emigna
@ Emigna Eu acho que é justo. Obrigado!
Riley #
12

Retina , 24 23 bytes

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

Experimente online!

Uma substituição de regex bastante simples. Combinamos cada caractere e tentamos encontrar uma cópia de 0 a 9 caracteres antes dele. Se o encontrarmos, substituímos o caractere pelo número de caracteres que precisávamos corresponder para obter a cópia.

Os resultados não correspondem exatamente aos casos de teste, porque este usa o maior dígito possível em vez do menor possível.

Martin Ender
fonte
4
O comprimento variável que o look-behind está trapaceando: p
Dada
8
@Dada Lookbehind de comprimento variável é o caminho da iluminação.
Martin Ender
Infelizmente é ... Se você está entediado, sinta-se à vontade para implementá-los dentro do Perl!
Dada
De acordo com o comentário do OP sobre a tarefa original, "Você pode usar qualquer dígito que desejar de 0 a 9, desde que seja válido." ... o maior possível deve ser válido
Doktor J
@DoktorJ sim, eu mudei depois que o OP adicionou esse esclarecimento.
Martin Ender
8

JavaScript (ES6), 74 57 54 bytes

Economizou 3 bytes graças a ETHproductions com o brilhante em p=/./gvez de p={}(inspirado em Neil)

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

Casos de teste

Arnauld
fonte
Como a string é garantida para não conter um dígito, você pode usar em svez de p?
7117 Neil
(Eu era capaz de outgolf o original findversão usando lastIndexOf, que é um pouco surpreendente, dado que é 11 letras ....)
Neil
@ Neil Eu não estou na frente de um computador agora, mas acho que isso não funcionaria, já que as strings JS são imutáveis.
Arnauld
2
Posso confirmar que a configuração de propriedades em literais de string não funciona. Mas ... parece que funciona com regex, então acho que você poderia fazer isso s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)para salvar 3 bytes.
ETHproductions
11
@YOU Eu realmente não sei o que aconteceu aqui, mas acontece que eu introduzi um bug para todos os navegadores na minha última edição. Agora está corrigido. Obrigado por perceber!
Arnauld
7

Haskell , 72 66 bytes

Agradecimentos a Laikoni por jogar 6 bytes!

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

Experimente online!

A função %mantém a sequência parcialmente processada em sentido inverso em seu segundo argumento, para que seja possível pesquisar os 10 primeiros elementos dessa sequência em busca de ocorrências do caractere que está sendo examinado. A submissão consiste na função sem nome (%"")que chama a função anterior com a string vazia como seu segundo argumento.

Leo
fonte
f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])salva dois bytes.
Laikoni
Espere, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]economiza ainda mais.
Laikoni
A reversão em movimento em vez de usar reverseeconomiza mais um byte: Experimente on-line!
Laikoni 7/07
@Laikoni Obrigado, isso é maravilhoso!
Leo
5

Python 2 , 64 bytes

s=''
for c in input():d=s[:~10:-1].find(c);s+=-d*c or`d`
print s

Experimente online!

xnor
fonte
Qual o sentido de usar ~10você não pode simplesmente usar -11?
precisa saber é o seguinte
3

Perl 5 , 36 bytes

35 bytes de código + -psinalizador.

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

Experimente online!

Algumas explicações:
O objetivo é substituir um caractere sem dígito ( \Dmas corresponde à referência anterior \1em minha regex) que é precedida por menos de 10 caracteres ( .{0,9}) e o mesmo caractere ( (\D)... \1) pelo comprimento do .{0,9}grupo ( length$2) E redoenquanto os personagens são substituídos.

dada
fonte
aparentemente, isso .*não é obrigatório, qualquer caractere válido no intervalo antes do dígito substituído está ok.
colsw
@ConnorLSW Sim, eu acabei de ver a atualização do desafio e modifiquei minha resposta, obrigado por apontar.
Dada
3

Python 2, 89 84 bytes

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

Experimente Online!

Repete a seqüência de caracteres inversa e cria uma nova seqüência com os números corretos inseridos.

viciado em matemática
fonte
3

Japonês , 18 bytes

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

Experimente online!

Explicação

£   ¯  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
fonte
2

JavaScript, 100 80 bytes

x=>x.split``.map((c,b,a)=>{for(i=0;i++<=9&&a[b-i]!=c;);return i>9?c:i-1}).join``

Experimente online!

fəˈnɛtɪk
fonte
2

05AB1E , 20 bytes

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

Experimente online!

Explicação

õ                     # 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
fonte
2

Python 3, 125 118 bytes

def p(x):print(x,end='')
l={}
for i,c in enumerate(input()):
 if l.get(c,i+9)<i+9:
  p(i-l[c]-1)
 else:
  p(c)
 l[c]=i

Experimente online!

L3viathan
fonte
2

C (tcc) , 113 bytes

Como a função cria uma cópia de uma sequência de entrada, o tamanho máximo da entrada é de 98 caracteres (mais que o suficiente para caber na entrada de teste mais longa). Obviamente, isso pode ser alterado para qualquer outro valor.

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;}

Experimente online!

Editar

-15 bytes. Obrigado Johan du Toit .

Maxim Mikhaylov
fonte
Agh! Limite a entrada para 98 caracteres e economize um byte!
pipe
Agradável solução, mas você pode economizar mais 15 bytes: 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 Thanks! Eu tenho uma pergunta. Como exatamente s [i] funciona como uma condição do loop for? Eu já vi isso muitas vezes nas respostas de outras pessoas neste site.
precisa
@Max Lawnboy. Você originalmente tinha o seguinte: 's [i] ^' \ 0 '', que é uma abreviação de 's [i]! =' \ 0 ''. O literal do caractere '\ 0' é igual a zero, para que você possa escrevê-lo assim: 's [i]! = 0'. A instrução if em C somente testa se o valor é avaliado como zero ou diferente de zero, portanto '! = 0' não é necessário.
Johan du Toit
100 bytes
tetocat
2

Java 7, 102 101 bytes

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);}

Experimente online!

-1 byte graças a Kevin Cruijssen . Eu sempre gosto de uma desculpa para usar o operador que vai.

Cutucar
fonte
Por que o --c>=0? Você pode substituí-lo por c-->0para salvar um byte.
Kevin Cruijssen
@KevinCruijssen De alguma forma, eu tinha na cabeça que eu precisava profanar, caso contrário, o cálculo real estaria errado ... Boa captura!
puxão
1

MATL, 31 30 bytes

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

Experimente em MATL Online!

Explicação

        % 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
fonte
Você pode ser um pouco fora, mas eu super não pode dizer onde. A entrada this is a testcede em this 222a1te52vez de this 222a19e52. O segundo tnão é convertido para 9.
Engineer Toast
@EngineerToast Haha thanks. Vou dar uma olhada.
Suever
1

PHP, 104 bytes

solução para a frente

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;

Soluções anteriores

Versões Online

PHP, 111 bytes

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 bytes

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;

Versão Online

Jörg Hülsermann
fonte
1

REXX, 124 125 bytes

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
fonte
Você pode estar um pouco desligado. Não conheço o REXX, mas presumo que o erro esteja na linha 7 onde está, em s<9vez de s<10ou s<=9. A entrada this is a testcede em this 222a1te52vez de this 222a19e52. O segundo tnão é convertido para 9. Experimente online
Engineer Toast
Obrigado, foi uma tentativa estúpida de economizar um byte. O código foi corrigido.
idrougge
1

C (gcc) , 117 103 bytes

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;}}

Experimente online!

103 bytes sem importação string.h, funciona com aviso. Se isso é contra as regras, eu vou puxar

Pretty Code:

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;
            }
}

Edições:

  • Alterado do LLVM para o gcc para permitir a declaração i, j implícita, a importação da biblioteca removida.
  • Adicionada função wrapper para conformidade
Eu sou.
fonte
Sugerir em (i=strlen(s);s[--i];)vez de(i=strlen(s)-1;s[i];i--)
ceilingcat 26/04