Веселіше з чутливими до строків (дуже) чутливими струнами


28

Натхненний цим викликом (або, точніше, неправильним його прочитанням), я зіткнувся з таким завданням:

З огляду на рядок введення S, поверніть порядок усіх великих літер та всіх малих символів. Залиште всі небуквені символи на місці. Наприклад:

Привіт Світ!

Зауважте, що велика літера W(перша велика літера) була замінена на H(остання). Те саме стосується і малих літер: 'd' (перша) замінюється на ( eостання), l(друга) замінюється на l(ручка-кінцева) ... Усі символи, що не належать до літер, залишаються на місці.

Вхідні дані

  • Введення - це рядок із лише символами ASCII в діапазоні 32-126.
  • Гарантоване введення має бути принаймні 1 символом, і воно не перевищує ліміт вашої мови.

Вихідні дані

  • Той самий рядок, з символами поміняний, як описано.

Додаткові правила

  • Стандартні лазівки заборонені
  • Відповідь має бути повною програмою або функцією, а не фрагментом чи запитом REPL.
  • , найкоротша відповідь у байтах.

Тестові справи

A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!

Можливо, ви хочете включити тест-шафу з двома знаками, моє оригінальне рішення спочатку не вдалось. (Виправлено безкоштовно, змінивши .+на .*)
ETHproductions

"Ледачий дож" нагадав мені про це: youtube.com/watch?v=W-d6uUSY9hk
FinW

Відповіді:


5

MATL , 14 байт

2:"t@Y2myy)Pw(

Спробуйте в MATL Online

Пояснення

        % Impicitly grab input as a string
2:      % Push the array [1, 2] to the stack
"       % For each value in this array
  t     % Duplicate the top element of the stack (S)
  @     % Get the current loop index
  Y2    % Load the predefined literal 1Y2 ('ABC...Z') on the first loop
        % and the predefined literal 2Y2 ('abc...z') on the second loop (M)
  m     % Create a logical array the length of S that is TRUE when a character is in the
        % array M and FALSE otherwise (B)
  yy    % Make a copy of both S and B
  )     % Grab just the letters of S that were in M using B as an index
  P     % Reverse this array
  w     % Flip the top two stack elements
  (     % Assign them back into the string
        % Implicit end of for loop and implicit display

1
Чудова робота! У мене було 2:"tttXk>f)5MP(Yo17 байт
Луїс Мендо

11

Сітківка , 19 байт

У сітківки немає прямого способу повернути рядок, але ми можемо це зробити, використовуючи етап сортування:

O^#`[a-z]
O^#`[A-Z]

Сортуйте ( O), читаючи їх як числа ( #), а потім оберніть впорядкування ( ^) всіх рядків, що відповідають заданому регулярному вираженню (малі літери першого рядка, а великі літери другого).

Це працює, тому що коли ми намагаємось читати рядки без числових символів як числа, вони вважаються такими 0, тому всі символи мають однакове значення для сортування. Оскільки сортування стабільне, вони залишаються в тому самому порядку, а їхнє повернення повертає вихідний рядок, перевернутий.

Спробуйте в Інтернеті!


10

Perl , 45 байт

44 байти коду + -pпрапор.

for$c(u,l){@T=/\p{L$c}/g;s/\p{L$c}/pop@T/ge}

Спробуйте в Інтернеті!

Unicode символи класи \p{Lu}та \p{Ll}збіги відповідно великих і малих літер.
Так /\p{L$c}/повернемо список усіх верхніх (або нижніх) літер (і збережемо всередині @T).
І тоді, регулярний вимір s/\p{$c}/pop@T/geзамінить кожну (верхню, а потім малу) літеру останньою літерою @T, видаляючи її з @T.


7

JavaScript (ES6), 74 73 71 70 байт

f=
s=>(g=r=>s=s.replace(r,_=>a.pop(),a=s.match(r)))(/[A-Z]/g,g(/[a-z]/g))
<input oninput=o.textContent=f(this.value)><pre id=o>

Редагувати: Збережено 1 байт завдяки @Arnauld.


4
Я знав, що є кращий спосіб ...
ETHproductions

5

JavaScript (ES6), 92 байти

s=>(F=(r,s)=>s.replace(r,([x],a,y)=>y+F(r,a)+x))(/[a-z](.*)([a-z])/,F(/[A-Z](.*)([A-Z])/,s))

Там вже є повинен бути спосіб , щоб скористатися схожістю між регулярними виразами ...

Фрагмент тесту


Чи передбачає це, що функція призначена змінній, що називається f? Чи не слід вважати кількість байтів?
steenbergh

@steenbergh Функція анонімна, її можна назвати так, як ви хочете
Kritixi Lithos

1
@steenbergh Nope, це анонімна функція, яка створює іншу функцію, Fа потім викликає її рекурсивно двічі. Зовнішня функція насправді не викликає себе в будь-якій точці.
ETHproductions

Чому ви використовуєте круглі дужки .*в регексах?
Лука

@Luke, щоб захопити цих персонажів ( ain ([x],a,y)=>)
ETHproductions

4

Perl 6 , 75 69 байт

{my @a=.comb;@(grep $_,@a).&{@$_=[R,] $_} for /<:Lu>/,/<:Ll>/;[~] @a}

Як це працює

  1. my @a=.comb;
    Розбийте рядок на символи та збережіть їх у масиві.

  2. for /<:Lu>/,/<:Ll>/
    Для двох регексів, що відповідають великим і малим літерам, відповідно ...

    • @(grep $_,@a)
      Отримайте фрагмент всіх записів масиву, який відповідає регулярному вираженню.

    • .&{@$_=[R,] $_}
      Призначте реверс фрагмента до себе.

  3. [~] @a
    Об'єднайте модифікований масив, щоб знову сформувати рядок, і поверніть його.


-6 байт шляхом крадіжки ідеї використовувати класи Unicode замість символьних діапазонів, з рішення @ Dada.


3

Желе , 14 байт

nŒlT,Ṛ$yJịŒsµ⁺

Спробуйте в Інтернеті!

Як це працює

nŒlT,Ṛ$yJịŒsµ⁺  Main link. Argument: s (string)

 Œl             Convert to lowercase.
n               Test for inequality.
   T            Truth; yield all indices of 1's.
    ,Ṛ$         Pair with its reverse. Yields [A, B] (pair of lists).
        J       Indices; yield I := [1, ..., len(s)].
       y        Translate; replace the integers of I that occur in A with the
                corresponding integers in B.
          Œs    Swapcase; yield s with swapped case.
         ị      Use the translated index list to index into s with swapped case.
            µ   Combine all links to the left into a chain.
             ⁺   Duplicate the chain, executing it twice.

не бути пустотливим, але .. 14 символів! = 23 байти :) mothereff.in/byte-counter
Gizmo

@Gizmo Jelly використовує кодову сторінку . Дивіться цей мета-пост для отримання додаткової інформації.
Suever

@Suever О, це охайно, сьогодні щось дізнався ^. ^
Gizmo

3

Утиліти Bash + Unix, 122 121 байт

f()(p=[^$1*
v="\)\([$1\)\("
for((n=99;n;n--)){
q="$q;s/^\($p$v.*$v$p\)$/\1\4\3\2\5/"
p=[^$1*[$1$p
}
sed $q)
f a-z]|f A-Z]

Спробуйте в Інтернеті!

Не дуже короткий; можливо, хтось може продовжити гольф далі.

Вхід на stdin, вихід на stdout.

Це буде правильно працювати на введеннях менше 200 символів.

(Насправді він правильно обробляє будь-який рядок із меншою кількістю 200 малих літер та менше 200 великих літер.)

Якщо ви збільшите 99 у коді до 102 (ціною одного додаткового байта), він буде обробляти рядки до 205 символів.

Однак ви не можете збільшити 99 у коді понад 102, оскільки тоді ви перевищите максимальну довжину аргументу sed.

Ось версія без особливих обмежень розміру вводу, але кількість трохи довше, 137 байт. (Ця довша версія записується у допоміжний файл під назвою t.)

f()(p=[^$1*
v="\)\([$1\)\("
for((n=`wc -c<t`;n;n--)){
sed -i "s/^\($p$v.*$v$p\)$/\1\4\3\2\5/" t
p=[^$1*[$1$p
})
cat>t
f a-z]
f A-Z]
cat t

Випробування:

for x in A Ok OK 'Hello, World!' 0123456789 'The quick brown Fox jumps over the lazy doge' odd racecar 'EtOn Em OsN R AaToNsIsIhT!!1!'
  do
    echo "$x"
    ./swapping3 <<<"$x"
    echo
  done

A
A

Ok
Ok

OK
KO

Hello, World!
Wdlro, Holle!

0123456789
0123456789

The quick brown Fox jumps over the lazy doge
Feg odyza lehtr Tev ospmu jxon wor bkci uqeh

odd
ddo

racecar
racecar

EtOn Em OsN R AaToNsIsIhT!!1!
ThIs Is NoT A RaNsOmEnOtE!!1!

Цікаво, що він не в TIO. ☹ Може залежати від sedреалізації, встановленої у вашій системі, але до GNU sedви можете додати -rпараметр та видалити \прохідні всі дужки.
манатура

2

Python 2 , 115 байт

s=input();u=str.isupper
exec"r='';i=0\nfor c in s:r+=c[u(c):]or filter(u,s)[~i];i+=u(c)\ns=r.swapcase();"*2
print s

Спробуйте в Інтернеті!


Чи можете ви замінити \ n на;?
Тім

На жаль, немає. Аргумент execаналізується як звичайний код Python, тому цикл for повинен знаходитись у власному рядку.
Денніс

2

Java (OpenJDK 8) , 271 байт

s->new String(new Error(){char[]o=s.toCharArray();char c;int b;{while(b++<2)for(int l=0,r=o.length;l<r;l++){for(--r;r>l&&f(r);r--);for(;l<r&&f(l);l++);if(l<r){o[l]=o[r];o[r]=c;}}}boolean f(int i){c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);}}.o)

Спробуйте в Інтернеті!


Ви можете зберегти кілька байт, перетворивши це в лямбда. s->new String...
нелінійний

1
@NonlinearFruit дякую! 294 -> 272, також виправлена ​​помилка під час повторного використання r a l без ініціалізації.
ДмитроСамойленко

Ласкаво просимо до PPCG! Деякі речі, які ви все-таки могли б пограти в гольф: char[]o=s.toCharArray();char c;int b;до char o[]=s.toCharArray(),c,b;; і обидва &&до &'; і c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);до c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);(всього 259 байт ). І я, мабуть, пропустив деякі речі, щоб більше пограти в гольф. Крім того, якщо ви цього ще не бачили, поради щодо гольфу на Java можуть бути цікавими для читання.
Kevin Cruijssen

1

R , 107 байт

u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));u[l]=u[rev(l)]};cat(intToUtf8(u,T),sep="")

Адаптований з моєї відповіді на пов'язаний виклик. Це значно простіше, ніж просто поміняти пари. Цікаво, чи зможу я отримати суб-100 з деякими гольфами ...

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.