Mathematica, 173 169 155 155 octets
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]&
Il s'agit d'une fonction prenant un tableau de deux chaînes, par exemple {"Foo","bAR"}
et produisant un tableau de deux chaînes. En le compressant spatialement, en réécrivant le schéma f@x
comme f[x]
partout où il apparaît, en développant les abréviations de notation ( f=0>1
aka False
, t=!f
aka True
et c=Characters
, u=ToUpperCaseQ
) et en ne remplaçant pas UpperCaseQ [#] par #==u@#
(ce caractère équivaut à sa version majuscule), c'est:
StringJoin /@ MapThread[#[#2] &, {
Reverse[
{ LetterQ[#], UpperCaseQ[#] } & /@ Characters[#] /.
{ {False, _} -> (# &), {True, True} -> ToUpperCase,
{True, False} -> ToLowerCase } & /@ #
],
Characters /@ #
}, 2] &
Interfaçage: la fin en &
fait une fonction. Son argument est inséré comme le "#" dans les deux instances de /@ #
. Par exemple, f=0>1; ... & [{"AAAbbb111", "Cc2Dd3Ee4"}]
produit la sortie {AaABbb111,CC2dd3Ee4}
.
Traitement: Raconté à l'extérieur habituel dans l'ordre:
- La sortie du
MapThread[...]
est une liste de deux listes de caractères. StringJoin est appliqué à chacune de ces deux listes de caractères pour produire une liste de deux chaînes, la sortie.
MapThread[#[#2]&, ... , 2]
agit sur un tableau de deux listes d'éléments 2 par n. La première liste est un tableau de fonctions 2 par n. La deuxième liste est un tableau de caractères 2 par n Characters /@ #
, les listes de caractères dans les deux chaînes d'entrée. Il travaille en profondeur 2, c'est-à-dire sur les fonctions et les caractères individuels.
Reverse[...]
échange les deux sous-listes de fonctions afin que MapThread applique les fonctions de la deuxième chaîne à la première chaîne et vice versa.
{ ... } &
est une fonction anonyme qui est appliquée à chacune des deux chaînes d'entrée.
{LetterQ[#], UpperCaseQ[#]} & /@ Characters[#]
divise une chaîne en une liste de caractères, puis remplace chaque caractère par deux listes d'éléments. Dans ces deux listes d'éléments, le premier élément est True
si le caractère est une lettre et False
sinon, de même, le deuxième élément indique si le caractère est en majuscule. UpperCaseQ[]
ne peut pas retourner vrai s'il ne reçoit pas de lettre.
/. {{False, _} -> (# &), {True, True} -> ToUpperCase, {True, False} -> ToLowerCase}
remplace ces deux listes d'éléments par des fonctions. (L'expansion des abréviations t
et f
se produit avant toute tentative de correspondance.) Si une liste à deux éléments a False
comme premier élément, elle est remplacée par la fonction (# &)
, la fonction d'identité. (Les parenthèses sont nécessaires, sinon la flèche se lie plus étroitement que l'esperluette.) Sinon, la liste des deux éléments commence par True
, le caractère était une lettre, et nous sortons les fonctions ToUpperCase
et ToLowerCase
correspondant à sa casse. (Vérifier ce dernier False
n'est pas nécessaire, en fait {_,_}->ToLowerCase
cela fonctionnerait, attraper tout ce qui n'a pas encore été remplacé, mais ce ne serait pas plus court et plus obscur.)
Le seul défi consistait à trouver un moyen succinct de compresser un tableau bidimensionnel de fonctions en un tableau d'arguments.
Edit: Merci à Büttner pour attraper @ Martin couper / coller linebreak antislashs « utile », les 1>0
et 1<0
abréviations, et aussi pour la direction de compter la longueur en octets pas de caractères (quels qu'ils sont :-))
Edit2: Merci encore à @Martin Büttner pour avoir souligné que la pollution de l'espace de noms global est un golf acceptable, me rappelant une application de fonction de caractère et suggérant de remplacer les deux fonctions majuscules par une abréviation pour l'une et d'utiliser l'une pour émuler l'autre (sauvegarde quatre caractères). (Je pense qu'il l'a déjà fait. :-))