Mehr Spaß mit case- (sehr) sensiblen Strings

28

Inspiriert von dieser Herausforderung (oder genauer gesagt durch falsches Lesen) habe ich die folgende Herausforderung gefunden:

Wenn Sie eine Eingabezeichenfolge S haben, kehren Sie die Reihenfolge aller Groß- und Kleinbuchstaben um. Belassen Sie alle Zeichen, die keine Buchstaben sind. Zum Beispiel:

Hallo Welt!

Beachten Sie, dass der Großbuchstabe W(der erste Großbuchstabe) durch H(den letzten) ersetzt wurde. Gleiches gilt für die Kleinbuchstaben: 'd' (der erste) wird durch e(der letzte) ersetzt, l(der zweite) durch l(der letzte) ... Alle Nichtbuchstaben bleiben an Ort und Stelle.

Eingang

  • Die Eingabe ist eine Zeichenfolge mit nur ASCII-Zeichen im Bereich 32-126.
  • Die Eingabe ist garantiert mindestens 1 Zeichen lang und überschreitet nicht das Limit Ihrer Sprache.

Ausgabe

  • Dieselbe Zeichenfolge, wobei die Zeichen wie beschrieben vertauscht wurden.

Zusätzliche Regeln

  • Standardlücken sind verboten
  • Die Antwort muss ein vollständiges Programm oder eine Funktion sein, kein Snippet oder ein REPL-Eintrag.
  • , die kürzeste Antwort in Bytes gewinnt.

Testfälle

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
quelle
Vielleicht möchten Sie einen 2-Zeichen-Testfall einbinden, meine ursprüngliche Lösung schlug darauf zunächst fehl. ( .+.*
Kostenlos behoben
"Lazy Doge" hat mich daran erinnert: youtube.com/watch?v=W-d6uUSY9hk
FinW

Antworten:

5

MATL , 14 Bytes

2:"t@Y2myy)Pw(

Probieren Sie es bei MATL Online aus

Erläuterung

        % 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
quelle
1
Gut gemacht! Ich hatte 2:"tttXk>f)5MP(Yofür 17 Bytes
Luis Mendo
11

Netzhaut , 19 Bytes

Retina hat keine direkte Möglichkeit, einen String umzukehren, aber wir können dies tun, indem wir die Sortierstufe ausnutzen:

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

Sortieren ( O), sie als Zahlen lesen ( #) und dann die Reihenfolge umkehren (^ ) aller Zeichenfolgen um, die mit der angegebenen Regex übereinstimmen (Kleinbuchstaben für die erste Zeile und Großbuchstaben für die zweite Zeile).

Dies funktioniert, weil beim Versuch, Zeichenfolgen ohne numerische Zeichen als Zahlen zu lesen, diese wie folgt behandelt werden 0 , sodass alle Zeichen den gleichen Wert für die Sortierung haben. Da die Sortierung stabil ist, werden sie in derselben Reihenfolge belassen, und beim Umkehren wird die ursprüngliche Zeichenfolge umgekehrt zurückgegeben.

Probieren Sie es online!

Löwe
quelle
10

Perl , 45 Bytes

44 Byte Code + -pFlag.

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

Probieren Sie es online!

Unicode-Zeichen werden klassifiziert \p{Lu}und \p{Ll}entsprechen Groß- und Kleinbuchstaben.
So /\p{L$c}/wird die Liste aller Groß- (oder Kleinbuchstaben) zurückgegeben (und darin gespeichert @T).
Und dann ersetzt der reguläre Ausdruck s/\p{$c}/pop@T/gejeden Buchstaben (Groß- und Kleinbuchstaben) durch den letzten Buchstaben von, @Twährend er von entfernt wird @T.

Dada
quelle
7

JavaScript (ES6), 74 73 71 70 Byte

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>

Bearbeiten: 1 Byte dank @Arnauld gespeichert.

Neil
quelle
4
Ich wusste, dass es einen besseren Weg gibt ...
ETHproductions
5

JavaScript (ES6), 92 Byte

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

Es hat bekam ein Weg , um die Vorteile der Ähnlichkeit zwischen dem regulären Ausdrücken sein ...

Testschnipsel

ETHproductions
quelle
Geht man davon aus, dass die Funktion einer aufgerufenen Variablen zugewiesen ist f? Sollte das nicht in der Byteanzahl sein?
steenbergh
@steenbergh Die Funktion ist anonym, es kann aufgerufen werden, was immer Sie wollen
Kritixi Lithos
1
@steenbergh Nein, es ist eine anonyme Funktion, die eine andere Funktion erstellt Fund sie dann zweimal rekursiv aufruft. Die äußere Funktion nennt sich eigentlich zu keinem Zeitpunkt.
ETHproductions
Warum verwenden Sie Klammern .*in regulären Ausdrücken?
Luke
@ Luke, um diese Charaktere (die ain ([x],a,y)=>) zu erfassen
ETHproductions
4

Perl 6 , 75 69 Bytes

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

Wie es funktioniert

  1. my @a=.comb;
    Teilen Sie die Zeichenfolge in Zeichen auf und speichern Sie sie in einem Array.

  2. for /<:Lu>/,/<:Ll>/
    Für zwei Regexes, die mit Groß- und Kleinbuchstaben übereinstimmen ...

    • @(grep $_,@a)
      Holen Sie sich einen Ausschnitt aller Array-Einträge, die dem regulären Ausdruck entsprechen.

    • .&{@$_=[R,] $_}
      Weisen Sie sich die Rückseite des Slice zu.

  3. [~] @a
    Verketten Sie das geänderte Array, um erneut eine Zeichenfolge zu bilden, und geben Sie sie zurück.


-6 Bytes durch Diebstahl der Idee, Unicode-Klassen anstelle von Zeichenbereichen zu verwenden, aus der @ Dada-Lösung.

smls
quelle
3

Jelly, 14 bytes

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

Try it online!

How it works

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
quelle
not to be nitpicky but.. 14 characters != 23 bytes :) mothereff.in/byte-counter
Gizmo
@Gizmo Jelly uses a codepage. See this meta post for more information.
Suever
@Suever Oh that's neat, learned something today ^.^
Gizmo
3

Bash + Unix utilities, 122 121 bytes

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]

Try it online!

Not really very short; maybe someone can golf it further.

Input on stdin, output on stdout.

This will work correctly on inputs of less than 200 characters.

(Actually it correctly handles any string with fewer than 200 lower-case letters and fewer than 200 upper-case letters.)

If you increase the 99 in the code to 102 (at the cost of one additional byte), it will handle strings up to 205 characters.

However, you can't increase the 99 in the code beyond 102 since you'll then exceed sed's maximum argument length.

Here's a version without any particular input size limitation, but the count is a little longer, 137 bytes. (This longer version writes to an auxiliary file named 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

Test runs:

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
quelle
Interesting that it fails in TIO. ☹ May depend on the sed implementation installed on your system, but to GNU sed you can add -r option and remove the \ escaping of all parenthesis.
manatwork
2

Python 2, 115 bytes

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

Try it online!

Dennis
quelle
Can you replace \n with ;?
Tim
Unfortunately, no. The argument of exec is parsed as usual Python code, so the for loop must be on its own line.
Dennis
2

Java (OpenJDK 8), 271 bytes

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)

Try it online!

DmitrySamoylenko
quelle
You could save some bytes by making this into a lambda. s->new String...
NonlinearFruit
1
@NonlinearFruit thank you! 294 -> 272, also fixed mistake when r an l was reused without initialization.
DmitrySamoylenko
Welcome to PPCG! Some things you could still golf: char[]o=s.toCharArray();char c;int b; to char o[]=s.toCharArray(),c,b;; and both && to &'; and c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c); to c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c); (259 bytes in total). And I probably missed some things to golf it more. Also, if you haven't seen it yet, tips for golfing in Java might be interesting to read.
Kevin Cruijssen
1

R, 107 bytes

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

Adapted from my response to the linked challenge. This is considerably easier than just swapping pairs. I wonder if I could get sub 100 with some golfs...

Try it online!

Sumner18
quelle