Saltar al contenido

Cifrado de valla ferroviaria

Lía, miembro de nuestro equipo de trabajo, nos hizo el favor de crear este post porque domina muy bien este tema.

Solución:

Python 133 bytes

def cipher(t,r):
 m=r*2-2;o='';j=o.join
 for i in range(r):s=t[i::m];o+=i%~-r and j(map(j,zip(s,list(t[m-i::m])+[''])))or s
 return o

Ejemplo de uso:

>>> print cipher('FOOBARBAZQUX', 3)
FAZOBRAQXOBU

>>> print cipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 4)
AGMSYBFHLNRTXZCEIKOQUWDJPV

>>> print cipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 5)
AIQYBHJPRXZCGKOSWDFLNTVEMU

>>> print cipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 6)
AKUBJLTVCIMSWDHNRXEGOQYFPZ

Nota: los resultados de los recuentos de rieles pares son diferentes a los del código que proporcionó, pero parecen ser correctos. Por ejemplo, 6 rieles:

A         K         U
 B       J L       T V
  C     I   M     S   W
   D   H     N   R     X
    E G       O Q       Y
     F         P         Z

corresponde a AKUBJLTVCIMSWDHNRXEGOQYFPZy no AKUTBLVJICMSWXRDNHQYEOGZFP como su código produce.

La idea básica es que cada carril se puede encontrar directamente tomando string rebanadas [i::m]dónde i es el número de tren (0-indexado), y m es (num_rails - 1)*2. Los rieles internos también deben entretejerse con [m-i::m], que se consigue comprimiendo y uniendo los dos conjuntos de personajes. Debido a que el segundo de estos puede ser potencialmente un carácter más corto, se rellena con un carácter que se supone que no aparece en ninguna parte (_), y luego ese carácter se elimina si es necesario se convierte en una lista y se rellena con un espacio vacío string.


Una forma un poco más legible por humanos:

def cipher(text, rails):
  m = (rails - 1) * 2
  out = ''
  for i in range(rails):
    if i % (rails - 1) == 0:
      # outer rail
      out += text[i::m]
    else:
      # inner rail
      char_pairs = zip(text[i::m], list(text[m-i::m]) + [''])
      out += ''.join(map(''.join, char_pairs))
  return out

APL 52 41

i←⍞⋄n←⍎⍞⋄(,((⍴i)⍴(⌽⍳n),1↓¯1↓⍳n)⊖(n,⍴i)⍴(n×⍴i)↑i)~' '

Si el texto de entrada string yo y el key número n están preinicializados, la solución se puede acortar en 9 caracteres. Ejecutar la solución contra los ejemplos dados por primo da respuestas idénticas:

FOOBARBAZQUX
3
FAZOBRAQXOBU
      
ABCDEFGHIJKLMNOPQRSTUVWXYZ
4
AGMSYBFHLNRTXZCEIKOQUWDJPV
      
ABCDEFGHIJKLMNOPQRSTUVWXYZ
5
AIQYBHJPRXZCGKOSWDFLNTVEMU
  
ABCDEFGHIJKLMNOPQRSTUVWXYZ
6
AKUBJLTVCIMSWDHNRXEGOQYFPZ

En una reflexión más profunda, parece haber una solución más corta basada en índices:

i[⍋+1,(y-1)⍴((n←⍎⍞)-1)/1 ¯1×1 ¯1+y←⍴i←⍞]

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *