Mathematica, 173 169 155 byte
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]&
Questa è una funzione che prende una matrice di due stringhe, ad es. {"Foo","bAR"}
E produce una matrice di due stringhe. Un-spazialmente-comprimerlo, riscrivere lo schema f@x
come f[x]
laddove appare, ampliando le abbreviazioni notazione ( f=0>1
alias False
, t=!f
alias True
, c=Characters
e u=ToUpperCaseQ
), e non-sostituzione UpperCaseQ [#] con #==u@#
(questo carattere è uguale sua versione maiuscolo), è:
StringJoin /@ MapThread[#[#2] &, {
Reverse[
{ LetterQ[#], UpperCaseQ[#] } & /@ Characters[#] /.
{ {False, _} -> (# &), {True, True} -> ToUpperCase,
{True, False} -> ToLowerCase } & /@ #
],
Characters /@ #
}, 2] &
Interfaccia: il finale lo &
rende una funzione. Il suo argomento è inserito come "#" in entrambe le istanze di /@ #
. Ad esempio f=0>1; ... & [{"AAAbbb111", "Cc2Dd3Ee4"}]
produce l'output {AaABbb111,CC2dd3Ee4}
.
Elaborazione: indicata normalmente all'esterno per:
- L'output di
MapThread[...]
è un elenco di due elenchi di caratteri. StringJoin viene applicato a ciascuna di queste due liste di caratteri per produrre un elenco di due stringhe, l'output.
MapThread[#[#2]&, ... , 2]
agisce su una matrice di due elenchi di elementi 2 per n. Il primo elenco è un array di funzioni 2 per n. Il secondo elenco è un array di caratteri 2 per n Characters /@ #
, gli elenchi di caratteri nelle due stringhe di input. Funziona a profondità 2, cioè sulle funzioni e sui singoli caratteri.
Reverse[...]
scambia le due liste secondarie di funzioni in modo che MapThread applichi le funzioni della seconda stringa alla prima stringa e viceversa.
{ ... } &
è una funzione anonima che viene applicata a ciascuna delle due stringhe di input.
{LetterQ[#], UpperCaseQ[#]} & /@ Characters[#]
divide una stringa in un elenco di caratteri, quindi sostituisce ogni carattere con due elenchi di elementi. In questi due elenchi di elementi, il primo elemento è True
se il carattere è una lettera e False
, in caso contrario, il secondo elemento indica se il carattere è maiuscolo. UpperCaseQ[]
non può restituire vero se non riceve una lettera.
/. {{False, _} -> (# &), {True, True} -> ToUpperCase, {True, False} -> ToLowerCase}
sostituisce questi due elenchi di elementi con funzioni. (L'espansione delle abbreviazioni t
e si f
verifica prima che venga tentata qualsiasi corrispondenza.) Se un elenco di due elementi ha False
come primo elemento, viene sostituito con la funzione (# &)
, la funzione identità. (Le parentesi sono necessarie, altrimenti la freccia si lega più strettamente della e commerciale). Altrimenti l'elenco dei due elementi inizia con True
, il carattere era una lettera e vengono emesse le funzioni ToUpperCase
e ToLowerCase
corrispondenti al suo caso. (Il controllo di quest'ultimo False
non è necessario, infatti {_,_}->ToLowerCase
funzionerebbe, catturando tutto ciò che non è stato ancora sostituito, ma questo non sarebbe più breve e più oscuro.)
L'unica sfida era capire un modo sintetico per comprimere una serie di funzioni bidimensionali in una serie di argomenti.
Modifica: Grazie a @Martin Büttner per la cattura di "utili" barre rovesciate, le abbreviazioni 1>0
e le interruzioni di riga 1<0
, e anche per la guida a contare la lunghezza in byte e non i caratteri (qualunque siano :-))
Edit2: Ulteriore grazie a @Martin Büttner per aver sottolineato che inquinare lo spazio dei nomi globale è un golf accettabile, ricordandomi un'applicazione di una funzione di carattere e suggerendo di sostituire le due funzioni maiuscole con un'abbreviazione per uno e di utilizzare l'una per emulare l'altro (salvando quattro caratteri). (Penso che l'abbia già fatto. :-))