Code Golf - Word Scrambler
-
07-07-2019 - |
Pregunta
Responda con el código fuente más corto posible para un programa que convierta un texto sin formato arbitrario a su texto cifrado correspondiente, siguiendo la entrada y salida de muestra que he proporcionado a continuación. Puntos de bonificación * por el menor tiempo de CPU o la menor cantidad de memoria utilizada.
Ejemplo 1:
Texto sin formato: El rápido zorro marrón salta sobre el perro perezoso. Supercalifragilisticexpialidocious!
Texto cifrado: eTh kiquc nobrw xfo smjup rvoe eth yalz .odg! uioiapeislgriarpSueclfaiitcxildcos
Ejemplo 2:
Texto sin formato: 123 1234 12345 123456 1234567 12345678 123456789
Texto cifrado: 312 4213 53124 642135 7531246 86421357 975312468
Reglas:
- La puntuación se define para incluirse con la palabra más cercana.
- El centro de una palabra se define como techo ((strlen (palabra) +1) / 2).
- El espacio en blanco se ignora (o se contrae).
- Las palabras extrañas se mueven a la derecha primero. Incluso las palabras se mueven a la izquierda primero.
Puede pensar que lee todos los demás caracteres hacia atrás (comenzando desde el final de la palabra), seguido de los caracteres restantes hacia adelante. Corporación = & Gt; XoXpXrXtXoX = & Gt; niaorCoprto.
Gracias a quienes señalaron la inconsistencia en mi descripción. Esto ha llevado a muchos de ustedes por el camino equivocado, por lo que me disculpo. La regla n. ° 4 debería aclarar las cosas.
* Los puntos de bonificación solo se otorgarán si Jeff Atwood decide hacerlo. Como no he consultado con él, las posibilidades son escasas. Lo siento.
Solución
Python, 50 caracteres
Para entrada en i
:
' '.join(x[::-2]+x[len(x)%2::2]for x in i.split())
Versión alternativa que maneja su propio IO:
print ' '.join(x[::-2]+x[len(x)%2::2]for x in raw_input().split())
Un total de 66 caracteres si se incluyen espacios en blanco. (Técnicamente, el print
podría omitirse si se ejecuta desde una línea de comando, ya que el valor evaluado del código se muestra como salida de forma predeterminada).
Versión alternativa con reduce
:
' '.join(reduce(lambda x,y:y+x[::-1],x) for x in i.split())
59 caracteres.
Versión original (tanto pares como impares van a la derecha primero) para una entrada en <=>:
' '.join(x[::2][::-1]+x[1::2]for x in i.split())
48 caracteres incluyendo espacios en blanco.
Otra versión alternativa que (aunque un poco más larga) es un poco más eficiente:
' '.join(x[len(x)%2-2::-2]+x[1::2]for x in i.split())
(53 caracteres)
Otros consejos
J , 58 caracteres
>,&.>/({~(,~(>:@+:@i.@-@<.,+:@i.@>.)@-:)@<:@#)&.><;.2,&' '
Haskell , 64 caracteres
unwords.map(map snd.sort.zip(zipWith(*)[0..]$cycle[-1,1])).words
Bueno, de acuerdo, 76 si agrega el requisito " import List
" ;.
Python - 69 caracteres
(incluidos espacios en blanco y saltos de línea)
Esto maneja todas las E / S.
for w in raw_input().split():
o=""
for c in w:o=c+o[::-1]
print o,
Perl, 78 caracteres
Para entrada en $_
. Si eso no es aceptable, agregue seis caracteres para $_=<>;
o $_=$s;
al principio. La nueva línea es solo para legibilidad.
for(split){$i=length;print substr$_,$i--,1,''while$i-->0;
print"$_ ";}print $/
C, 140 caracteres
Bien formateado:
main(c, v)
char **v;
{
for( ; *++v; )
{
char *e = *v + strlen(*v), *x;
for(x = e-1; x >= *v; x -= 2)
putchar(*x);
for(x = *v + (x < *v-1); x < e; x += 2)
putchar(*x);
putchar(' ');
}
}
Comprimido:
main(c,v)char**v;{for(;*++v;){char*e=*v+strlen(*v),*x;for(x=e-1;x>=*v;x-=2)putchar(*x);for(x=*v+(x<*v-1);x<e;x+=2)putchar(*x);putchar(32);}}
Lua
130 funciones de caracteres, 147 programas de funcionamiento de caracteres
Lua no tiene suficiente amor en el golf de código, tal vez porque es difícil escribir un programa corto cuando tienes palabras clave largas como function
/ end
, if
/ then
/ <pre></pre>
, etc.
Primero escribo la función de manera detallada con explicaciones, luego la reescribo como una función independiente comprimida, luego llamo a esa función en el argumento único especificado en la línea de comando.
Tuve que formatear el código con etiquetas <=> porque Markdown hace un trabajo horrible al formatear Lua.
Técnicamente, podría obtener un programa en ejecución más pequeño al incorporar la función, pero es más modular de esta manera :)
t = "The quick brown fox jumps over the lazy dog. Supercalifragilisticexpialidocious!" T = t:gsub("%S+", -- for each word in t... function(w) -- argument: current word in t W = "" -- initialize new Word for i = 1,#w do -- iterate over each character in word c = w:sub(i,i) -- extract current character -- determine whether letter goes on right or left end W = (#w % 2 ~= i % 2) and W .. c or c .. W end return W -- swap word in t with inverted Word end) -- code-golf unit test assert(T == "eTh kiquc nobrw xfo smjup rvoe eth yalz .odg !uioiapeislgriarpSueclfaiitcxildcos") -- need to assign to a variable and return it, -- because gsub returns a pair and we only want the first element f=function(s)c=s:gsub("%S+",function(w)W=""for i=1,#w do c=w:sub(i,i)W=(#w%2~=i%2)and W ..c or c ..W end return W end)return c end -- 1 2 3 4 5 6 7 8 9 10 11 12 13 --34567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -- 130 chars, compressed and written as a proper function print(f(arg[1])) --34567890123456 -- 16 (+1 whitespace needed) chars to make it a functioning Lua program, -- operating on command line argument
Salida:
$ lua insideout.lua 'The quick brown fox jumps over the lazy dog. Supercalifragilisticexpialidocious!' eTh kiquc nobrw xfo smjup rvoe eth yalz .odg !uioiapeislgriarpSueclfaiitcxildcos
Todavía soy bastante nuevo en Lua, así que me gustaría ver una solución más corta si hay una.
Para un cifrado mínimo en todos los argumentos a stdin, podemos hacer 111 caracteres:
for _,w in ipairs(arg)do W=""for i=1,#w do c=w:sub(i,i)W=(#w%2~=i%2)and W ..c or c ..W end io.write(W ..' ')end
Pero este enfoque genera un espacio final como algunas de las otras soluciones.
Para una entrada en s
:
f=lambda t,r="":t and f(t[1:],len(t)&1and t[0]+r or r+t[0])or r
" ".join(map(f,s.split()))
Python, 90 caracteres incluyendo espacios en blanco.
TCL
125 caracteres
set s set f foreach l {}
$f w [gets stdin] {$s r {}
$f c [split $w {}] {$s r $c[string reverse $r]}
$s l "$l $r"}
puts $l
Bash - 133, suponiendo que la entrada esté en la variable $ w
Bonita
for x in $w; do
z="";
for l in `echo $x|sed 's/\(.\)/ \1/g'`; do
if ((${#z}%2)); then
z=$z$l;
else
z=$l$z;
fi;
done;
echo -n "$z ";
done;
echo
Comprimido
for x in $w;do z="";for l in `echo $x|sed 's/\(.\)/ \1/g'`;do if ((${#z}%2));then z=$z$l;else z=$l$z;fi;done;echo -n "$z ";done;echo
Ok, entonces genera un espacio final.