Più divertimento con le stringhe case (molto) sensibili


28

Ispirato da questa sfida (o, più specificamente, leggendola male), ho escogitato la seguente sfida:

Data una stringa di input S, invertire l'ordine di tutti i caratteri maiuscoli e tutti i caratteri minuscoli. Lascia in posizione tutti i caratteri non di lettere. Per esempio:

Ciao mondo!

Notare che la lettera maiuscola W(la prima lettera maiuscola) è stata sostituita con H(l'ultima). Lo stesso vale per le lettere minuscole: 'd' (il primo) viene scambiato con e(l'ultimo), l(secondo) viene sostituito con l(pen-ultimate) ... Tutti i caratteri non lettera vengono lasciati al loro posto.

Ingresso

  • L'input è una stringa con solo caratteri ASCII nell'intervallo 32-126.
  • L'immissione è garantita per almeno 1 carattere e non supererà il limite della tua lingua.

Produzione

  • La stessa stringa, con i caratteri scambiati come descritto.

Regole aggiuntive

  • Sono vietate le scappatoie standard
  • La risposta deve essere un programma completo o una funzione, non uno snippet o una voce REPL.
  • vince il , la risposta più breve in byte.

Casi test

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!

Potresti voler includere un testcase da 2 caratteri, la mia soluzione originale inizialmente non è riuscita. (Risolto gratuitamente cambiando .+in .*)
ETHproductions

"lazy doge" mi ha ricordato questo: youtube.com/watch?v=W-d6uUSY9hk
FinW

Risposte:


5

MATL , 14 byte

2:"t@Y2myy)Pw(

Provalo su MATL Online

Spiegazione

        % 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
Ottimo lavoro! Ho avuto 2:"tttXk>f)5MP(Yoper 17 byte
Luis Mendo l'

11

Retina , 19 byte

Retina non ha un modo diretto per invertire una stringa, ma possiamo farlo sfruttando la fase di smistamento:

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

Ordina ( O), leggendoli come numeri ( #), quindi invertendo l'ordinamento ( ^), di tutte le stringhe corrispondenti alla regex specificata (lettere minuscole per la prima riga e lettere maiuscole per la seconda).

Questo funziona perché quando proviamo a leggere stringhe senza caratteri numerici come numeri vengono trattati come 0, quindi tutti i caratteri hanno lo stesso valore per l'ordinamento. Poiché l'ordinamento è stabile, vengono lasciati nello stesso ordine e l'inversione restituisce la stringa originale invertita.

Provalo online!


10

Perl , 45 byte

44 byte di codice + -pflag.

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

Provalo online!

Classi di caratteri Unicode \p{Lu}e \p{Ll}corrispondenze rispettivamente lettere maiuscole e minuscole.
Quindi /\p{L$c}/restituirà l'elenco di tutte le lettere maiuscole (o minuscole) (e la memorizzerà all'interno @T).
E poi, il regex s/\p{$c}/pop@T/gesostituirà ogni lettera (maiuscola, quindi minuscola) con l'ultima lettera di @Tmentre la rimuove da @T.


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>

Modifica: salvato 1 byte grazie a @Arnauld.


4
Ho saputo che c'era un modo migliore ...
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))

Ci ha ottenuto di essere un modo per sfruttare la somiglianza tra i regex ...

Test snippet


Questo presuppone che la funzione sia assegnata a una variabile chiamata f? Non dovrebbe essere nel conteggio dei byte?
steenbergh,

@steenbergh La funzione è anonima, può essere chiamata come vuoi tu
Kritixi Lithos

1
@steenbergh No, è una funzione anonima che crea un'altra funzione Fe la chiama ricorsivamente due volte. La funzione esterna non si chiama in realtà in nessun momento.
ETHproductions

Perché usi le parentesi .*nei regex?
Luca,

@Luke per catturare quei personaggi (the ain ([x],a,y)=>)
ETHproductions

4

Perl 6 , 75 69 byte

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

Come funziona

  1. my @a=.comb;
    Dividi la stringa in caratteri e salvali in un array.

  2. for /<:Lu>/,/<:Ll>/
    Per due regex corrispondenti lettere maiuscole e minuscole, rispettivamente ...

    • @(grep $_,@a)
      Ottieni una porzione di tutte le voci di array corrispondenti alla regex.

    • .&{@$_=[R,] $_}
      Assegna il retro della sezione a se stesso.

  3. [~] @a
    Concatena l'array modificato per formare nuovamente una stringa e restituirlo.


-6 byte rubando l'idea di utilizzare le classi Unicode invece degli intervalli di caratteri, dalla soluzione di @Dada.


3

Gelatina , 14 byte

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

Provalo online!

Come funziona

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.

non essere pignoli ma .. 14 caratteri! = 23 byte :) mothereff.in/byte-counter
Gizmo

@Gizmo Jelly usa una tabella codici . Vedi questo meta post per maggiori informazioni.
Suever,

@Suever Oh, è bello, ho imparato qualcosa oggi ^. ^
Gizmo,

3

Utilità Bash + Unix, 122 121 byte

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]

Provalo online!

Non molto molto corto; forse qualcuno può golf ulteriormente.

Input su stdin, output su stdout.

Funzionerà correttamente su input di meno di 200 caratteri.

(In realtà gestisce correttamente qualsiasi stringa con meno di 200 lettere minuscole e meno di 200 lettere maiuscole.)

Se aumenti 99 nel codice a 102 (al costo di un byte aggiuntivo), gestirà stringhe fino a 205 caratteri.

Tuttavia, non puoi aumentare i 99 nel codice oltre 102 poiché supererai quindi la lunghezza massima dell'argomento sed.

Ecco una versione senza particolari limiti di dimensioni di input, ma il conteggio è un po 'più lungo, 137 byte. (Questa versione più lunga scrive in un file ausiliario chiamato 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

Esecuzioni di test:

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!

Interessante che fallisca in TIO. ☹ Può dipendere seddall'implementazione installata sul tuo sistema, ma a GNU sedpuoi aggiungere -run'opzione e rimuovere la \fuga di tutte le parentesi.
Manatwork

2

Python 2 , 115 byte

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

Provalo online!


Puoi sostituire \ n con;?
Tim

Sfortunatamente no. L'argomento di execviene analizzato come al solito codice Python, quindi il ciclo for deve essere sulla propria riga.
Dennis,

2

Java (OpenJDK 8) , 271 byte

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)

Provalo online!


È possibile salvare alcuni byte trasformandolo in un lambda. s->new String...
NonlinearFruit

1
@NonlinearFruit grazie! 294 -> 272, risolto anche l'errore quando r an la veniva riutilizzata senza inizializzazione.
DmitrySamoylenko,

Benvenuti in PPCG! Alcune cose che potresti ancora giocare char[]o=s.toCharArray();char c;int b;a golf: a char o[]=s.toCharArray(),c,b;; ed entrambi &&a &'; e c=o[i];return b>1?!Character.isUpperCase(c):!Character.isLowerCase(c);a c=o[i];Character x=c;return b>1?!x.isUpperCase(c):!x.isLowerCase(c);( 259 byte in totale ). E probabilmente mi sono perso alcune cose per giocare a golf di più. Inoltre, se non l'hai ancora visto, i suggerimenti per giocare a golf in Java potrebbero essere interessanti da leggere.
Kevin Cruijssen,

1

R , 107 byte

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

Adattato dalla mia risposta alla sfida collegata. Questo è notevolmente più semplice del semplice scambio di coppie. Mi chiedo se potrei ottenere sub 100 con alcuni golf ...

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.