Więcej zabawy z (bardzo) wrażliwymi na wielkość liter ciągami

28

Zainspirowany tym wyzwaniem (a ściślej jego błędnym odczytaniem) opracowałem następujące wyzwanie:

Biorąc pod uwagę ciąg wejściowy S, odwróć kolejność wszystkich wielkich liter i wszystkich małych liter. Pozostaw wszystkie znaki inne niż litery na miejscu. Na przykład:

Witaj świecie!

Zauważ, że wielkie litery W(pierwsza duża litera) zostały zastąpione przez H(ostatnie). To samo dotyczy małych liter: „d” (pierwszy) jest zamieniany na e(ostatni), l(drugi) jest zastępowany przez l(pen-ultimate) ... Wszystkie znaki nieliterowe pozostają na miejscu.

Wkład

  • Dane wejściowe to ciąg znaków zawierający tylko znaki ASCII z zakresu 32–126.
  • Dane wejściowe mają co najmniej 1 znak i nie przekroczą limitu Twojego języka.

Wydajność

  • Ten sam ciąg znaków, zamieniając znaki zgodnie z opisem.

Dodatkowe zasady

  • Standardowe luki są zabronione
  • Odpowiedź musi być pełnym programem lub funkcją, a nie fragmentem kodu lub wpisem REPL.
  • , wygrywa najkrótsza odpowiedź w bajtach.

Przypadki testowe

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!
Steenbergh
źródło
Być może chcesz dołączyć 2-znakową skrzynkę testową, moje oryginalne rozwiązanie na początku się nie powiodło. (Naprawiono bezpłatnie, zmieniając .+na .*)
ETHprodukcje
„leniwy doge” przypomniał mi o tym: youtube.com/watch?v=W-d6uUSY9hk
FinW

Odpowiedzi:

5

MATL , 14 bajtów

2:"t@Y2myy)Pw(

Wypróbuj w MATL Online

Wyjaśnienie

        % 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
Suever
źródło
1
Dobra robota! Miałem 2:"tttXk>f)5MP(Yo17 bajtów
Luis Mendo
11

Retina , 19 bajtów

Retina nie ma bezpośredniego sposobu na odwrócenie łańcucha, ale możemy to zrobić, wykorzystując etap sortowania:

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

Sortuj ( O), odczytując je jako liczby (# ), a następnie odwróć kolejność ( ^) wszystkich ciągów pasujących do podanego wyrażenia regularnego (małe litery w pierwszym wierszu i wielkie litery w drugim).

Działa to, ponieważ gdy próbujemy odczytać ciągi bez znaków numerycznych jako liczby, są one traktowane jako 0 , więc wszystkie znaki mają tę samą wartość do sortowania. Ponieważ sortowanie jest stabilne, pozostają one w tej samej kolejności, a odwrócenie ich powoduje odwrócenie oryginalnego łańcucha.

Wypróbuj online!

Lew
źródło
10

Perl , 45 bajtów

44 bajty kodu + -pflaga.

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

Wypróbuj online!

Klasy znaków Unicode \p{Lu}i \p{Ll}dopasowanie odpowiednio wielkich i małych liter.
Zwróci więc /\p{L$c}/listę wszystkich wielkich (lub małych) liter (i zapisze ją w środku @T).
A następnie wyrażenie regularne s/\p{$c}/pop@T/gezastąpi każdą (wielką, a następnie małą) literę ostatnią literą @Tpodczas usuwania @T.

Dada
źródło
7

JavaScript (ES6), 74 73 71 70 bajtów

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>

Edycja: Zapisano 1 bajt dzięki @Arnauld.

Neil
źródło
4
I wiedział, że był to lepszy sposób ...
ETHproductions
5

JavaScript (ES6), 92 bajty

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))

Tam dostał się sposób, aby skorzystać z podobieństwa regexes ...

Testowy fragment kodu

ETHprodukcje
źródło
Czy zakłada to, że funkcja jest przypisana do zmiennej o nazwie f? Czy nie powinno to być w liczbie bajtów?
steenbergh
@steenbergh Funkcja jest anonimowa, można ją nazwać czymkolwiek chcesz
Kritixi Lithos
1
@steenbergh Nie, to anonimowa funkcja, która tworzy inną funkcję, Fa następnie wywołuje ją dwukrotnie. Funkcja zewnętrzna nie wywołuje się w żadnym momencie.
ETHprodukcje
Dlaczego używasz nawiasów .*w wyrażeniach regularnych?
Łukasz
@Luke, aby uchwycić te postacie (the ain ([x],a,y)=>)
ETHproductions
4

Perl 6 , 75 69 bajtów

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

Jak to działa

  1. my @a=.comb;
    Podziel ciąg na znaki i zapisz je w tablicy.

  2. for /<:Lu>/,/<:Ll>/
    Dla dwóch wyrażeń regularnych pasujących odpowiednio do wielkich i małych liter ...

    • @(grep $_,@a)
      Uzyskaj wycinek wszystkich pozycji tablicy pasujących do wyrażenia regularnego.

    • .&{@$_=[R,] $_}
      Przypisz odwrotność plasterka do siebie.

  3. [~] @a
    Połącz zmodyfikowaną tablicę, aby ponownie utworzyć ciąg, i zwróć go.


-6 bajtów, kradnąc pomysł użycia klas Unicode zamiast zakresów znaków, z rozwiązania @ Dada.

smls
źródło
3

Galaretka , 14 bajtów

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

Wypróbuj online!

Jak to działa

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.
Dennis
źródło
nie być złośliwym, ale .. 14 znaków! = 23 bajty :) mothereff.in/byte-counter
Gizmo
@Gizmo Jelly używa strony kodowej . Zobacz ten meta post, aby uzyskać więcej informacji.
Suever
@Suever Och, to fajnie, nauczyłem się czegoś dzisiaj ^. ^
Gizmo
3

Narzędzia Bash + Unix, 122 121 bajtów

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]

Wypróbuj online!

Niezbyt krótko; może ktoś może zagrać w golfa dalej.

Wejście na stdin, wyjście na stdout.

Działa to poprawnie na wejściach mniejszych niż 200 znaków.

(W rzeczywistości poprawnie obsługuje dowolny ciąg zawierający mniej niż 200 małych liter i mniej niż 200 wielkich liter).

Jeśli zwiększysz 99 w kodzie do 102 (kosztem jednego dodatkowego bajtu), będzie on obsługiwał łańcuchy o długości do 205 znaków.

Nie możesz jednak zwiększyć 99 w kodzie powyżej 102, ponieważ wtedy przekroczysz maksymalną długość argumentu sed.

Oto wersja bez żadnego konkretnego ograniczenia rozmiaru wejściowego, ale liczba ta jest nieco dłuższa, 137 bajtów. (Ta dłuższa wersja zapisuje do pliku pomocniczego o nazwie 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

Przebiegi testowe:

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!
Mitchell Spector
źródło
Ciekawe, że zawodzi w TIO. ☹ Może zależeć od sedimplementacji zainstalowanej w twoim systemie, ale do GNU sedmożesz dodać -ropcję i usunąć \ucieczkę wszystkich nawiasów.
manatwork
2

Python 2 , 115 bajtów

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

Wypróbuj online!

Dennis
źródło
Czy możesz zastąpić \ n przez;?
Tim
Niestety nie. Argument execparsowany jest jak zwykły kod Pythona, więc pętla for musi znajdować się w osobnej linii.
Dennis
2

Java (OpenJDK 8) , 271 bajtów

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)

Wypróbuj online!

Dmitrij Samojlenko
źródło
Możesz zaoszczędzić kilka bajtów, przekształcając je w lambda. s->new String...
NielinioweOwoce
1
@NonlinearFruit dziękuję! 294 -> 272, również naprawiono błąd, gdy r an l został ponownie użyty bez inicjalizacji.
DmitrySamoylenko
Witamy w PPCG! Niektóre rzeczy można jeszcze golfowe: char[]o=s.toCharArray();char c;int b;do char o[]=s.toCharArray(),c,b;; i oba &&do &”; i c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);do c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);( łącznie 259 bajtów ). I pewnie brakowało mi kilku rzeczy, aby bardziej zagrać w golfa. Ponadto, jeśli jeszcze go nie widziałeś, porady dotyczące gry w golfa w Javie mogą być interesujące do przeczytania.
Kevin Cruijssen
1

R , 107 bajtów

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="")

Dostosowane z mojej odpowiedzi na powiązane wyzwanie. Jest to znacznie łatwiejsze niż zwykła zamiana par. Zastanawiam się, czy mógłbym dostać mniej niż 100 z kilkoma golfami ...

Wypróbuj online!

Sumner18
źródło