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 é uma função que pega uma matriz de duas strings, por exemplo, {"Foo","bAR"}e gera uma matriz de duas strings. Un-espacialmente comprimindo-la, reescrevendo o esquema f@xcomo f[x]onde quer que apareça, ampliando as abreviaturas Notation ( f=0>1aka False, t=!faka True, c=Characterse u=ToUpperCaseQ), e un-substituindo UpperCaseQ [#] com #==u@#(este personagem é igual a sua versão uppercased), é:
StringJoin /@ MapThread[#[#2] &, {
Reverse[
{ LetterQ[#], UpperCaseQ[#] } & /@ Characters[#] /.
{ {False, _} -> (# &), {True, True} -> ToUpperCase,
{True, False} -> ToLowerCase } & /@ #
],
Characters /@ #
}, 2] &
Interface: o trailing &torna isso uma função. Seu argumento é inserido como o "#" nas duas instâncias de /@ #. Por exemplo, f=0>1; ... & [{"AAAbbb111", "Cc2Dd3Ee4"}]produz a saída {AaABbb111,CC2dd3Ee4}.
Processamento: Contado normalmente fora em ordem:
- A saída de
MapThread[...]é uma lista de duas listas de caracteres. StringJoin é aplicado a cada uma dessas duas listas de caracteres para produzir uma lista de duas seqüências, a saída.
MapThread[#[#2]&, ... , 2]atua em uma matriz de duas listas de elementos 2 por n. A primeira lista é uma matriz de 2 por n de funções. A segunda lista é uma matriz de caracteres 2 por n Characters /@ #, as listas de caracteres nas duas seqüências de entrada. Funciona na profundidade 2, ou seja, nas funções e nos caracteres individuais.
Reverse[...] troca as duas sublistas de funções para que o MapThread aplique as funções da segunda sequência à primeira e vice-versa.
{ ... } & é uma função anônima aplicada a cada uma das duas seqüências de entrada.
{LetterQ[#], UpperCaseQ[#]} & /@ Characters[#]divide uma string em uma lista de caracteres e substitui cada caractere por duas listas de elementos. Nessas duas listas de elementos, o primeiro elemento é Truese o caractere é uma letra e False, do mesmo modo, o segundo elemento indica se o caractere está em maiúsculas. UpperCaseQ[]não pode retornar verdadeiro se não receber uma carta.
/. {{False, _} -> (# &), {True, True} -> ToUpperCase, {True, False} -> ToLowerCase}substitui essas duas listas de elementos por funções. (A expansão das abreviações te focorre antes da tentativa de correspondência.) Se uma lista de dois elementos tiver Falsecomo primeiro elemento, ela será substituída pela função (# &), a função de identidade. (Os parênteses são necessários, caso contrário, a seta se liga mais firmemente que o e comercial.) Caso contrário, a lista de dois elementos começa com True, o caractere era uma letra e produzimos as funções ToUpperCasee ToLowerCasecorrespondentes ao seu caso. (A verificação deste último Falseé desnecessária, de fato {_,_}->ToLowerCasefuncionaria, capturando qualquer coisa que ainda não tivesse sido substituída, mas isso não seria mais curto e mais obscuro.)
O único desafio foi descobrir uma maneira sucinta de compactar uma matriz bidimensional de funções em uma matriz de argumentos.
Edit: Obrigado a @Martin Büttner por capturar barras invertidas de corte / colar "úteis", as 1>0e 1<0abreviações, e também pela orientação para contar o comprimento em bytes, não em caracteres (sejam eles :-))
Edit2: Mais agradecimentos a @Martin Büttner por apontar que poluir o espaço para nome global é um golfe aceitável, lembrando-me de um aplicativo de função de caractere e sugerindo substituir as duas funções em maiúsculas por uma abreviação de um e usar o outro para emular o outro (salvar quatro caracteres). (Eu acho que ele já fez isso antes. :-))