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 AKUBJLTVCIMSWDHNRXEGOQYFPZ
y 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 ( se convierte en una lista y se rellena con un espacio vacío string._
), y luego ese carácter se elimina si es necesario
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←⍞]