Mathematica, 173 169 155 байтов
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]&
Это функция, принимающая массив из двух строк, например, {"Foo","bAR"}
и выводящая массив из двух строк. Un-пространственно-сжать его, перезапись схему , f@x
как f[x]
там , где она появляется, расширяя обозначения сокращений ( f=0>1
он же False
, t=!f
иначе True
, c=Characters
и u=ToUpperCaseQ
), и снимите замены UpperCaseQ [#] с #==u@#
(этот символ равен ее версии в верхнем регистре), это:
StringJoin /@ MapThread[#[#2] &, {
Reverse[
{ LetterQ[#], UpperCaseQ[#] } & /@ Characters[#] /.
{ {False, _} -> (# &), {True, True} -> ToUpperCase,
{True, False} -> ToLowerCase } & /@ #
],
Characters /@ #
}, 2] &
Интерфейс: трейлинг &
делает это функцией. Его аргумент вставляется как "#" в обоих случаях /@ #
. Например, f=0>1; ... & [{"AAAbbb111", "Cc2Dd3Ee4"}]
производит вывод {AaABbb111,CC2dd3Ee4}
.
Обработка: Сказано в обычном снаружи в порядке:
- Выводом
MapThread[...]
является список из двух списков символов. StringJoin применяется к каждому из этих двух списков символов, чтобы сформировать список из двух строк, выводимых.
MapThread[#[#2]&, ... , 2]
действует на массив из двух списков элементов размером 2 на n. Первый список представляет собой массив функций 2 на n. Второй список представляет собой массив символов 2 на n Characters /@ #
, списки символов в двух входных строках. Работает на глубине 2, т. Е. Над функциями и отдельными персонажами.
Reverse[...]
меняет местами два подсписка функций, так что MapThread будет применять функции второй строки к первой строке и наоборот.
{ ... } &
является анонимной функцией, которая применяется к каждой из двух входных строк.
{LetterQ[#], UpperCaseQ[#]} & /@ Characters[#]
разбивает строку на список символов, а затем заменяет каждый символ двумя списками элементов. В этих двух списках элементов первый элемент - это True
если символ является буквой, а в False
противном случае аналогичным образом второй элемент указывает, является ли символ заглавным. UpperCaseQ[]
не может вернуть истину, если не получил письмо.
/. {{False, _} -> (# &), {True, True} -> ToUpperCase, {True, False} -> ToLowerCase}
заменяет эти два списка элементов функциями. (Расширение сокращений t
и f
происходит до того , как совпадающая попытку.) Если список из двух элементов имеют в False
качестве своего первого элемента, он заменяется функцией (# &)
, функция идентификации. (Скобки необходимы, в противном случае стрелка связывается более тесно, чем амперсанд.) В противном случае список из двух элементов начинается с того True
, что символ представляет собой букву, и мы выводим функции ToUpperCase
и ToLowerCase
соответствуют их регистру. (Проверять это последнее False
не нужно, на самом деле {_,_}->ToLowerCase
сработало бы, отлавливая все, что еще не было заменено, но это было бы не короче и не мрачнее.)
Единственная проблема заключалась в том, чтобы найти краткий способ объединить двумерный массив функций в массив аргументов.
Изменить: Благодаря @Martin Büttner для ловли «полезно» вырезать / вставить LineBreak обратных косых черт, то 1>0
и 1<0
аббревиатуры, а также для указания посчитать длину в байтах не символы (независимо от тех , которые :-))
Edit2: Кроме того, спасибо @Martin Büttner за то, что он указал на то, что загрязнение глобального пространства имен является приемлемым гольфом, напомнив мне об одном приложении функции символа и предложив заменить две заглавные функции на одну аббревиатуру и использовать одну для эмуляции другой (сохранение четыре символа). (Я думаю, что он делал это раньше. :-))