Plus amusant avec les cordes (très) sensibles à la casse

28

Inspiré par ce défi (ou, plus précisément, en le mal interprété), j'ai trouvé le défi suivant:

Étant donné une chaîne d'entrée S, inversez l'ordre de tous les caractères majuscules et de tous les caractères minuscules. Laissez tous les caractères non-lettre en place. Par exemple:

Bonjour le monde!

Notez que la majuscule W(la première lettre majuscule) a été remplacée par H(la dernière). Il en va de même pour les lettres minuscules: 'd' (le premier) est échangé avec e(le dernier), l(le deuxième) est remplacé par l(pen-ultimate) ... Tous les caractères non-lettre sont laissés en place.

Contribution

  • L'entrée est une chaîne contenant uniquement des caractères ASCII compris entre 32 et 126.
  • La saisie est garantie sur au moins 1 caractère et ne dépassera pas la limite de votre langue.

Sortie

  • Cette même chaîne, avec les caractères échangés comme décrit.

Règles supplémentaires

  • Les failles standard sont interdites
  • La réponse doit être un programme complet ou une fonction, pas un extrait de code ou une entrée REPL.
  • , réponse la plus courte en octets gagne.

Cas de 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!
steenbergh
la source
Vous voudrez peut-être inclure un testcase de 2 caractères, ma solution d'origine a échoué au début. (Fixé sans frais en passant .+à .*)
ETHproductions
"doge paresseux" me l'a rappelé: youtube.com/watch?v=W-d6uUSY9hk
Fin le

Réponses:

5

MATL , 14 octets

2:"t@Y2myy)Pw(

Essayez-le sur MATL Online

Explication

        % 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
la source
1
Bon travail! J'avais 2:"tttXk>f)5MP(Yopour 17 octets
Luis Mendo
11

Rétine , 19 octets

Retina n'a pas de moyen direct pour inverser une chaîne, mais nous pouvons le faire en exploitant l'étape de tri:

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

Trier ( O), en les lisant sous forme de nombres ( #), puis inverser l'ordre ( ^), de toutes les chaînes correspondant à l'expression régulière donnée (lettres minuscules pour la première ligne et lettres majuscules pour la seconde).

Cela fonctionne parce que lorsque nous essayons de lire des chaînes sans caractères numériques comme des nombres, elles sont traitées comme 0si tous les caractères ont la même valeur pour le tri. Étant donné que le tri est stable, ils sont laissés dans le même ordre et leur inversion renvoie la chaîne d'origine inversée.

Essayez-le en ligne!

Leo
la source
10

Perl , 45 octets

44 octets de code + -pindicateur.

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

Essayez-le en ligne!

Classes de caractères Unicode \p{Lu}et \p{Ll}correspond respectivement aux lettres majuscules et minuscules.
Ainsi /\p{L$c}/, la liste de toutes les lettres majuscules (ou minuscules) sera retournée (et stockée à l'intérieur @T).
Et puis, l'expression régulière s/\p{$c}/pop@T/geremplacera chaque lettre (majuscule puis minuscule) par la dernière lettre de @Ttout en la supprimant @T.

Dada
la source
7

JavaScript (ES6), 74 73 71 70 octets

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>

Edit: 1 octet enregistré grâce à @Arnauld.

Neil
la source
4
Je savais qu'il y avait une meilleure façon ...
ETHproductions
5

JavaScript (ES6), 92 octets

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

Il a obtenu d'être un moyen de tirer profit de la similitude entre les expressions rationnelles ...

Extrait de test

ETHproductions
la source
Cela suppose-t-il que la fonction est affectée à une variable appelée f? Ne devrait-ce pas être dans le nombre d'octets?
steenbergh
@steenbergh La fonction est anonyme, elle peut être appelée comme vous voulez
Kritixi Lithos
1
@steenbergh Non, c'est une fonction anonyme qui crée une autre fonction Fpuis l'appelle récursivement deux fois. La fonction externe ne s'appelle en fait à aucun moment.
ETHproductions
Pourquoi utilisez-vous des parenthèses .*dans les expressions rationnelles?
Luke
@Luke pour capturer ces personnages (le adans ([x],a,y)=>)
ETHproductions
4

Perl 6 , 75 69 octets

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

Comment ça marche

  1. my @a=.comb;
    Divisez la chaîne en caractères et stockez-les dans un tableau.

  2. for /<:Lu>/,/<:Ll>/
    Pour deux expressions rationnelles correspondant respectivement aux lettres majuscules et minuscules ...

    • @(grep $_,@a)
      Obtenez une tranche de toutes les entrées de tableau correspondant à l'expression régulière.

    • .&{@$_=[R,] $_}
      Attribuez-lui l'inverse de la tranche.

  3. [~] @a
    Concaténez le tableau modifié pour former à nouveau une chaîne et renvoyez-le.


-6 octets en volant l'idée d'utiliser des classes Unicode au lieu de plages de caractères, dans la solution de @ Dada.

smls
la source
3

Gelée , 14 octets

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

Essayez-le en ligne!

Comment ça marche

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
la source
ne pas être tordu mais .. 14 caractères! = 23 octets :) mothereff.in/byte-counter
Gizmo
@Gizmo Jelly utilise une page de codes . Voir ce meta post pour plus d'informations.
Suever
@Suever Oh c'est bien, j'ai appris quelque chose aujourd'hui ^. ^
Gizmo
3

Utilitaires Bash + Unix, 122 121 octets

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]

Essayez-le en ligne!

Pas vraiment très court; peut-être que quelqu'un peut jouer au golf plus loin.

Entrée sur stdin, sortie sur stdout.

Cela fonctionnera correctement sur les entrées de moins de 200 caractères.

(En fait, il gère correctement toute chaîne contenant moins de 200 lettres minuscules et moins de 200 lettres majuscules.)

Si vous augmentez le 99 dans le code à 102 (au prix d'un octet supplémentaire), il traitera les chaînes jusqu'à 205 caractères.

Cependant, vous ne pouvez pas augmenter le 99 dans le code au-delà de 102, car vous dépasserez alors la longueur d'argument maximale de sed.

Voici une version sans limitation de taille d'entrée particulière, mais le nombre est un peu plus long, 137 octets. (Cette version plus longue écrit dans un fichier auxiliaire nommé 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

Essais:

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
la source
Intéressant qu'il échoue dans TIO. ☹ Peut dépendre de l' sedimplémentation installée sur votre système, mais à GNU sedvous pouvez ajouter une -roption et supprimer l' \échappement de toutes les parenthèses.
manatwork
2

Python 2 , 115 octets

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

Essayez-le en ligne!

Dennis
la source
Pouvez-vous remplacer \ n par;?
Tim
Malheureusement non. L'argument de execest analysé comme du code Python habituel, donc la boucle for doit être sur sa propre ligne.
Dennis
2

Java (OpenJDK 8) , 271 octets

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)

Essayez-le en ligne!

DmitrySamoylenko
la source
Vous pouvez économiser quelques octets en transformant cela en lambda. s->new String...
NonlinearFruit
1
@NonlinearFruit merci! 294 -> 272, correction d'une erreur lors de la réutilisation de r an l sans initialisation.
DmitrySamoylenko
Bienvenue chez PPCG! Certaines choses que vous pourriez encore jouer char[]o=s.toCharArray();char c;int b;au golf: pour char o[]=s.toCharArray(),c,b;; et les deux &&à &'; et 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 octets au total ). Et j'ai probablement raté certaines choses pour jouer au golf plus. De plus, si vous ne l'avez pas encore vu, des conseils pour jouer au golf à Java pourraient être intéressants à lire.
Kevin Cruijssen
1

R , 107 octets

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

Adapté de ma réponse au défi lié. C'est beaucoup plus facile que de simplement échanger des paires. Je me demande si je pourrais obtenir moins de 100 avec certains golfs ...

Essayez-le en ligne!

Sumner18
la source