Hagamos algo de "enciph5r47g"


35

Esta es la inversa de Hagamos algo de "deciph4r4ng"


En este desafío, su tarea es cifrar una cadena. Afortunadamente, el algoritmo es bastante simple: leyendo de izquierda a derecha, cada carácter de escritura típico (rango ASCII 32-126) debe ser reemplazado por un número N (0-9) para indicar que es el mismo que el carácter N + 1 posiciones delante de él. La excepción es cuando el carácter no aparece dentro de las 10 posiciones anteriores en la cadena original. En ese caso, simplemente debe imprimir el personaje nuevamente. Efectivamente, debería ser capaz de revertir la operación desde el desafío original.

Ejemplo

La cadena de entrada "Programming"se codificaría de esta manera:

Ejemplo 1

Por lo tanto, la salida esperada es "Prog2am0in6".

Aclaraciones y reglas.

  • La cadena de entrada contendrá caracteres ASCII en el rango 32 - 126 exclusivamente. Puede suponer que nunca estará vacío.
  • Se garantiza que la cadena original no contendrá ningún dígito.
  • Una vez que un carácter ha sido codificado, a su vez puede ser referenciado por un dígito posterior. Por ejemplo, "alpaca"debe codificarse como "alp2c1".
  • Las referencias nunca se ajustarán a la cadena: solo se puede hacer referencia a los caracteres anteriores.
  • Puede escribir un programa completo o una función, que imprime o genera el resultado.
  • Este es el código de golf, por lo que gana la respuesta más corta en bytes.
  • Las lagunas estándar están prohibidas.

Casos de prueba

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.

66
Veo que sus casos de prueba siempre usan el dígito más bajo posible para cualquier sustitución. ¿Es este comportamiento requerido, o podemos usar dígitos más altos también, cuando hay más de una posibilidad?
Leo

@Leo Puedes usar cualquier dígito que quieras 0-9 siempre que sea válido.
Engineer Toast el

Esto es como un codificador de movimiento al frente , excepto sin el movimiento :)
pipe

Respuestas:


6

05AB1E , 20 19 18 bytes

-2 Gracias a Emigna

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

Pruébalo en línea!

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

Creo que también )¹vDyåiDykëy}?y¸ìT£funciona.
Emigna

En realidad, combinando tu respuesta con la mía da õIvDyåiDykëy}?yìT£por 18 :)
Emigna

@Emigna Siéntase libre de actualizar la suya con eso :)
Riley

No lo habría pensado si no fuera por tu respuesta, así que deberías tenerlo. ¡Buen trabajo!
Emigna

@Emigna, supongo que es justo. ¡Gracias!
Riley

12

Retina , 24 23 bytes

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

Pruébalo en línea!

Una sustitución de expresiones regulares bastante simple. Emparejamos cada personaje e intentamos encontrar una copia de él de 0 a 9 caracteres antes. Si lo encontramos, reemplazamos el carácter con el número de caracteres que tuvimos que unir para llegar a la copia.

Los resultados no coinciden con los casos de prueba, porque este usa el dígito más grande posible en lugar del más pequeño posible.


44
La vigilancia de longitud variable es trampa: p
Dada

8
@Dada La mirada retrospectiva de longitud variable es el camino de la iluminación.
Martin Ender

Lamentablemente es ... Si estás aburrido, ¡no dudes en implementarlos dentro de Perl!
Dada

Según el comentario de OP sobre la tarea original, "Puede usar cualquier dígito que desee 0-9 siempre que sea válido" ... por lo tanto, el mayor posible debería ser válido
Doktor J

@DoktorJ sí, lo cambié después de que el OP agregó esa aclaración.
Martin Ender

8

JavaScript (ES6), 74 57 54 bytes

Ahorró 3 bytes gracias a ETHproductions con el brillante en p=/./glugar de p={}(inspirado en Neil)

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

Casos de prueba


Como se garantiza que la cadena no contiene un dígito, ¿puede usarla en slugar de p?
Neil

(Pude superar su findversión original usando lastIndexOf, lo cual es un poco sorprendente dado que tiene 11 letras de largo ...)
Neil

@Neil No estoy frente a una computadora en este momento, pero no creo que eso funcione ya que las cadenas JS son inmutables.
Arnauld

2
Puedo confirmar que establecer propiedades en literales de cadena no funciona. Pero ... parece que funciona con expresiones regulares, por lo que creo que podría hacer s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)para guardar 3 bytes.
ETHproductions

1
@YOU Realmente no sé qué pasó aquí, pero resulta que introduje un error para todos los navegadores en mi última edición. Esto ya está arreglado. ¡Gracias por notarlo!
Arnauld

7

Haskell , 72 66 bytes

¡Gracias a Laikoni por jugar al golf 6 bytes!

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

Pruébalo en línea!

La función %mantiene la cadena parcialmente procesada en reversa en su segundo argumento, por lo que puede buscar en los primeros 10 elementos de esta cadena las ocurrencias del carácter que está examinando. El envío consiste en la función sin nombre (%"")que llama a la función anterior con la cadena vacía como segundo argumento.


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])Guarda dos bytes.
Laikoni

Espera, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]ahorra aún más.
Laikoni

Invertir sobre la marcha en lugar de usar reverseguarda un byte adicional: ¡ Pruébelo en línea!
Laikoni

@Laikoni Gracias, ¡eso es maravilloso!
Leo


3

Perl 5 , 36 bytes

35 bytes de código + -pbandera.

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

Pruébalo en línea!

Algunas explicaciones:
El objetivo es reemplazar un carácter que no sea un dígito ( \Dpero corresponde a la referencia inversa \1en mi expresión regular) precedido por menos de 10 caracteres ( .{0,9}) y el mismo carácter ( (\D)... \1) por la longitud del .{0,9}grupo ( length$2) Y redomientras los personajes son reemplazados.


aparentemente .*no es obligatorio, cualquier carácter válido en el rango antes del dígito reemplazado está bien.
colsw

@ConnorLSW Sí, acabo de ver esa actualización del desafío y modifiqué mi respuesta, gracias por señalarlo.
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

Pruébalo en línea!

Itera a través de la cadena en reversa y construye una nueva cadena con los números correctos insertados.


3

Japt , 18 bytes

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

Pruébalo en línea!

Explicación

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

Pruébalo en línea!

Explicación

õ                     # 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 bytes

Como la función crea una copia de una cadena de entrada, el tamaño máximo de entrada es de 98 caracteres (más que suficiente para ajustarse a la entrada de prueba más larga). Por supuesto, esto se puede cambiar a cualquier otro 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;}

Pruébalo en línea!

Editar

-15 bytes. Gracias Johan du Toit .


Agh! ¡Limite la entrada a 98 caracteres y ahórrese un byte!
tubería

Buena solución pero puedes guardar otros 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 ¡Gracias! Tengo una pregunta. ¿Cómo funciona exactamente s [i] como condición del bucle for? Lo he visto muchas veces en las respuestas de otras personas en este sitio web.
Maxim Mikhaylov

@Max Lawnboy. Originalmente tenía lo siguiente: 's [i] ^' \ 0 '' que abreviatura de 's [i]! =' \ 0 ''. El carácter literal '\ 0' es igual a cero, por lo que puede escribirlo así: 's [i]! = 0'. La instrucción if en C solo prueba si el valor se evalúa a cero o no es cero, por lo que '! = 0' no es necesario.
Johan du Toit


2

Java 7, 102101 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);}

Pruébalo en línea!

-1 byte gracias a Kevin Cruijssen . Siempre disfruto de una excusa para usar el operador de referencia.


¿Por qué el --c>=0? Puede reemplazarlo c-->0para guardar un byte.
Kevin Cruijssen

@KevinCruijssen De alguna manera tenía en mi cabeza que necesitaba predecrementar, de lo contrario el cálculo real estaría mal ... ¡Buena captura!
Poke

1

MATL, 31 30 bytes

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

¡Pruébalo en MATL Online!

Explicación

        % 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

Usted puede ser un poco fuera pero súper no se puede saber dónde. La entrada this is a testrinde en this 222a1te52lugar de this 222a19e52. El segundo tno se convierte a 9.
Engineer Toast el

@EngineerToast Jaja gracias. Le daré un vistazo.
Suever

1

PHP, 104 bytes

solución directa

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;

Soluciones al revés

Versiones en linea

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;

Versión en línea


1

REXX, 124125 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

Puede que estés un poco apagado. No sé REXX pero supongo que el error está en la línea 7 donde tiene en s<9lugar de s<10o s<=9. La entrada this is a testrinde en this 222a1te52lugar de this 222a19e52. El segundo tno se convierte a 9. Pruébelo en línea
Engineer Toast

Gracias, fue un estúpido intento de eliminar un byte. El código ha sido arreglado.
idrougge

1

C (gcc) , 117103 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;}}

Pruébalo en línea!

103 bytes sin importación string.h, funciona con advertencia. Si esto va en contra de las reglas, lo tiraré

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

Ediciones:

  • Se cambió de LLVM a gcc para permitir la declaración implícita de i, j, se eliminó la importación de lib.
  • Se agregó un contenedor de funciones para el cumplimiento

Sugerir en (i=strlen(s);s[--i];)lugar de(i=strlen(s)-1;s[i];i--)
ceilingcat
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.