Mathematica, 173 169 155 bytes
f=0>1;t=!f;c=Characters;u=ToUpperCase;StringJoin/@MapThread[#@#2&,{Reverse[{LetterQ@#,#==(u@#)}&/@c@#/.{{f,_}->(#&),{t,t}->u,{t,f}->ToLowerCase}&/@#],c/@#},2]&
Esta es una función que toma una matriz de dos cadenas, por ejemplo, {"Foo","bAR"}
y genera una matriz de dos cadenas. Sin comprimir espacialmente, reescribiendo el esquema f@x
como f[x]
donde aparezca, expandiendo las abreviaturas de notación ( f=0>1
aka False
, t=!f
aka True
,c=Characters
y u=ToUpperCaseQ
), y poco reemplazando UpperCaseQ [#] con #==u@#
(este personaje es igual a su versión uppercased), que es:
StringJoin /@ MapThread[#[#2] &, {
Reverse[
{ LetterQ[#], UpperCaseQ[#] } & /@ Characters[#] /.
{ {False, _} -> (# &), {True, True} -> ToUpperCase,
{True, False} -> ToLowerCase } & /@ #
],
Characters /@ #
}, 2] &
Interfaz: el final &
hace de esto una función. Su argumento se inserta como el "#" en ambas instancias de /@ #
. Por ejemplo, f=0>1; ... & [{"AAAbbb111", "Cc2Dd3Ee4"}]
produce la salida {AaABbb111,CC2dd3Ee4}
.
Procesamiento: contado en el exterior habitual en orden:
- La salida de
MapThread[...]
es una lista de dos listas de caracteres. StringJoin se aplica a cada una de estas dos listas de caracteres para producir una lista de dos cadenas, la salida.
MapThread[#[#2]&, ... , 2]
actúa en una matriz de dos listas de elementos de 2 por n. La primera lista es una matriz de funciones de 2 por n. La segunda lista es una matriz de caracteres de 2 por n,Characters /@ #
, las listas de caracteres en las dos cadenas de entrada. Funciona en profundidad 2, es decir, en las funciones y caracteres individuales.
Reverse[...]
intercambia las dos sublistas de funciones para que MapThread aplique las funciones de la segunda cadena a la primera cadena y viceversa.
{ ... } &
es una función anónima que se aplica a cada una de las dos cadenas de entrada.
{LetterQ[#], UpperCaseQ[#]} & /@ Characters[#]
divide una cadena en una lista de caracteres, luego reemplaza cada carácter con dos listas de elementos. En estas listas de dos elementos, el primer elemento es True
si el carácter es una letra y False
, de lo contrario, el segundo elemento indica si el carácter es mayúscula. UpperCaseQ[]
no puede devolver verdadero si no recibe una carta.
/. {{False, _} -> (# &), {True, True} -> ToUpperCase, {True, False} -> ToLowerCase}
reemplaza estas dos listas de elementos con funciones. (La expansión de las abreviaturas t
y f
se produce antes de intentar cualquier juego.) Si una lista de dos elementos tiene False
como su primer elemento, es reemplazado con la función (# &)
, la función identidad. (Los paréntesis son necesarios, de lo contrario la flecha se une más estrechamente que el signo.) De lo contrario, los dos elementos de la lista comienza con True
el personaje era una carta, y las funciones de salida ToUpperCase
y ToLowerCase
correspondiente a su caso. (Verificar esto último False
es innecesario, de hecho {_,_}->ToLowerCase
funcionaría, atrapando cualquier cosa que aún no haya sido reemplazada, pero esto no sería más corto y más oscuro).
El único desafío fue encontrar una manera sucinta de comprimir una matriz de funciones bidimensional en una matriz de argumentos.
Editar: Gracias a @Martin Büttner por capturar barras diagonales de corte / pegado "útiles", abreviaturas 1>0
y 1<0
abreviaturas, y también por la guía para contar la longitud en bytes, no en caracteres (cualesquiera que sean :-))
Edit2: Además, gracias a @Martin Büttner por señalar que contaminar el espacio de nombres global es un juego de golf aceptable, recordándome la aplicación de una función de personaje y sugiriendo reemplazar las dos funciones en mayúscula por una abreviatura para una y usar la una para emular la otra (guardar cuatro caracteres) (Creo que ya ha hecho esto antes :-))