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.

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

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.


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


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.


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


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.


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.


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


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

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!


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 .


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


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.


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

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


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

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

Sugerir em (i=strlen(s);s[--i];)vez de(i=strlen(s)-1;s[i];i--)
ceilingcat 26/04
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.