Déchiffrer ces chaînes très sensibles à la casse

53

Objectif

C'est un défi simple. Votre but est de déchiffrer une chaîne en échangeant chaque lettre avec la lettre suivante du même cas, tout en laissant les caractères non-lettre inchangés.

exemple

Explication pas à pas

  1. Le premier caractère est un E. Nous cherchons la lettre suivante en majuscule: c’est a C. Nous échangeons ces caractères, ce qui conduit à CdoE!.

  2. Nous passons au caractère suivant: c’est un d. Nous cherchons la lettre suivante en minuscule: c’est a o. Nous échangeons ces caractères, ce qui conduit à CodE!.

  3. Nous passons au caractère suivant: il s’agit de celui dque nous venons de déplacer ici. Nous l'ignorons car il a déjà été traité.

  4. Nous passons au caractère suivant: il s’agit de celui Equi a été déplacé ici à l’étape 1. Nous l'ignorons car il a déjà été traité.

  5. Nous passons au caractère suivant: c’est un !. Nous l'ignorons, car ce n'est pas une lettre.

Règles

  • Vous pouvez supposer que la chaîne d'entrée est composée exclusivement de caractères ASCII imprimables, compris entre 32 et 126.

  • Vous pouvez écrire un programme complet ou une fonction qui imprime ou renvoie le résultat.

  • Si la chaîne d'entrée contient un nombre impair de lettres, la dernière lettre restante ne peut pas être remplacée par une autre et doit rester en place, quelle que soit sa casse. La même logique s'applique si la chaîne contient un nombre pair de lettres, mais un nombre impair de lettres majuscules et un nombre impair de lettres minuscules.

  • C'est du code-golf, donc la réponse la plus courte en octets est gagnante. Les échappatoires standard sont interdites.

Cas de test

Input : lLEhW OroLd!
Output: hELlO WorLd!

Input : rpGOZmaimgn uplRzse naC DEoO LdGf
Output: prOGRamming puzZles anD COdE GoLf

Input : eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg
Output: tHe quICK BROWN fOx juMPS OvER THE LAzy dOg

Input : NraWgCi: Nsas-eNEiTIsev rNsiTG!!
Output: WarNiNg: Case-sENsITive sTriNG!!

Cas de test pas si aléatoires:

Input : (^_^)
Output: (^_^)

Input : AWCTY HUOS RETP
Output: WATCH YOUR STEP

Input : hwn oeesd acsp nawyya
Output: who needs caps anyway

Input : SpMycaeIesKyBorekn
Output: MySpaceKeyIsBroken

Input : D's mroyr, Ivam. I'e faardi I act'n od htta.
Output: I'm sorry, Dave. I'm afraid I can't do that.
Arnauld
la source
Je suppose qu'un commentaire similaire est valable si l'entrée contient un nombre pair de lettres, mais un nombre impair de lettres majuscules et un nombre impair de lettres minuscules.
Greg Martin
14
C'est un défi vraiment intelligent ... J'aime aussi le fait que des scénarios de test puissent être faits en tapant une chaîne minuscule, en changeant au hasard certaines lettres en majuscules, puis en exécutant exactement le même programme qui résout le problème!
Greg Martin
1
@GregMartin J'ai découvert que le problème est sa propre inverse car lorsque j'ai essayé un scénario de test, j'ai tapé accidentellement la sortie au lieu de l'entrée :-)
Luis Mendo
Je pense que vous devriez inclure des scénarios de test avec plus d'un caractère ASCII non lettre ... Je pense que certaines implémentations pourraient les échanger accidentellement les unes avec les autres, alors que cela n'est pas censé se produire.
Greg Martin
3
Les tests devraient probablement inclure une chaîne sans lettres majuscules et une chaîne sans aucune lettre.
Dennis

Réponses:

4

Gelée , 21 20 19 18 octets

s2UF,
nŒlTÇyJịŒsµ⁺

Essayez-le en ligne!

Comment ça fonctionne

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.
    Ç         Call the helper link. 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.


s2UF,         Helper link. Argument: J (list of indices)

s2            Split J into pairs. If the length is odd, the last list will be
              a singleton list.
  U           Upend; reverse each pair. This is a no-op for singletons lists.
   F          Flatten, concatenating the pairs.
    ,          Pair the previous result with J.
Dennis
la source
18

Retina , 53 octets

Pas vraiment intelligent, mais une solution propre et assez lisible

([a-z])(.*?)([a-z])
$3$2$1
([A-Z])(.*?)([A-Z])
$3$2$1

Essayez-le en ligne!

Leo
la source
9

MATL , 22 octets

2:"tttk<f2etAZ))P5M(Yo

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Comment ça fonctionne

2:"       % Do the following twice
  ttt     %   Input string (implicit). Push three more copies
  k       %   Convert to lowercase
  <f      %   Indices of characters that had their code point increased by
          %   the lowercase conversion, i.e. that were uppercase letters
  2e      %   Convert to 2-row matrix. This pads a zero in the lower-right 
          %   corner if necessary
  tAZ)    %   Keep only columns that don't contain zeros. Thus if there
          %   was a character that can't be swapped it will be ignored             
  )       %   Get 2-row matrix of characters at those positions
  P       %   Flip vertically. This does the swapping
  5M      %   Push matrix of original indices again
  (       %   Write the swapped characters onto their original positions
  Yo      %   Change case. In the first iteration, this prepares the
          %   string so the second iteration will process the letters that
          %   were originally lowercase. In the second iteration, it
          %   undoes the change of case 
          % End (implicit)
          % Display (implicit)
Luis Mendo
la source
6

Utilitaires Bash + Unix, 77 62 57 56 54 octets

sed -r "s/([$1)([^$1*)([$1)/\3\2\1/g"||$0 a-z]|$0 A-Z]

Entrée en stdin. Sortie en stdout.

(Dans cette dernière version, stderr est également écrit, mais le consensus du PPCG semble être que c'est OK - stderr est simplement ignoré. )

Edit 1: Merci à @Dennis pour 15 octets! Améliorations: (a) Prise d’entrée via stdin; (b) combiner 2 scripts sed en un seul; et (c) remplacer tr par substitution par expansion du paramètre bash; (b) et (c) ont disparu dans Edit 2.

Edit 2: Plus court de 5 octets supplémentaires. Utilisé un appel de fonction pour remplacer (b) et (c) dans l’édition 1.

Edit 3: Un octet supplémentaire - passé] dans les arguments de la fonction.

Edit 4: Remplacement des deux appels de fonction par des appels au programme même s’il n’a pas d’argument.

Banc d'essai et sortie d'échantillon:

for x in 'lLEhW OroLd!' 'rpGOZmaimgn uplRzse naC DEoO LdGf' 'eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg' 'NraWgCi: Nsas-eNEiTIsev rNsiTG!!' '(^_^)' 'AWCTY HUOS RETP' 'hwn oeesd acsp nawyya' 'SpMycaeIesKyBorekn' "D's mroyr, Ivam. I'e faardi I act'n od htta."; do ./swapping <<<"$x" 2>/dev/null; done

hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
tHe quICK BROWN fOx juMPS OvER THE LAzy dOg
WarNiNg: Case-sENsITive sTriNG!!
(^_^)
WATCH YOUR STEP
who needs caps anyway
MySpaceKeyIsBroken
I'm sorry, Dave. I'm afraid I can't do that.
Mitchell Spector
la source
6

ES6, 185 95 octets

i=>(o=[...i]).map((c,j)=>/[a-z]/i.test(c)?o[e=c>"Z"]=1/(b=o[e])?o[o[j]=o[b],b]=c:j:0)&&o.join``

Solution sévèrement raccourcie à l'aide de @Neil, @Arnauld et @ edc65

Explication

f = i =>
  // Get array of characters from input string
  (o = [...i])
    .map((c, j) => 
      // Check if it's a text character, otherwise skip it
      /[a-z]/i.test(c) ? 
        // Get last character position for case
        // merged with setting a variable for if the character is lowercase
        // merged with storing the current case character position,  
        // under properties on the array (with keys "true" or "false")
        o[e = c>"Z"] =
          // Check if there exists a character position to switch with
          // merged with storing the current position for quick access
          1/(b=o[e]) ? 
            // This statement will end up returning the Array subset, 
            // which will be falsy in the above conditional since (1/[])==false
            o[
              // Switch left character to the right
              o[j]=o[b]
            // Switch right character to the left
            ,b]=c : 
            // No character exists for case, so return current character position
            j
         // It was not a text character, so do nothing
         :0
      )
  // Join array and return as result
  && o.join``;

`lLEhW OroLd!
NraWgCi: Nsas-eNEiTIsev rNsiTG!!
rpGOZmaimgn uplRzse naC DEoO LdGf
eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg
(^_^)
AWCTY HUOS RETP
hwn oeesd acsp nawyya
SpMycaeIesKyBorekn
D's mroyr, Ivam. I'e faardi I act'n od htta`
  .split`\n`
  .map(testCase => console.log(f(testCase)));

Jan
la source
6 octets, les parenthèses englobantes sont redondantes lorsque nous supprimons la deuxième déclaration :) Bien.
Jan
2
S'il vous plaît ignorer mon dernier commentaire. Voici le 99:/[a-z]/i.test(c)?o[e=c>"Z"]=1/(b=o[e])?[o[b],o[j]]=[c,o[b]]:j:0
Arnauld
2
[o[b],o[j]]=[c,o[b]]pourrait êtreo[o[j]=o[b],b]=c
edc65
Le vrai coup de maître ici utilise true et false comme index pour un tableau
edc65
Merci les gars, jusqu'à 95 maintenant. Il devient très difficile de documenter la solution de façon sensée. XD @ edc65 ils sont stockés en tant que propriétés sur l'objet tableau, pas des index. Ouais, Arnauld a découvert qu'ils étaient stockés dans le tableau de caractères, mais la réutilisation de l'objet était plus un hasard, je pense, qui venait d'une suggestion distincte. Initialement, il était stocké sur un objet séparé, ce qui était bien entendu totalement inutile pour la portée du défi.
Jan
3

Python , 82 octets

lambda s:S(r.lower(),t,S(r,t,s))
import re
S=re.sub
r='([A-Z])(.*?)'*2
t=r'\3\2\1'

Essayez-le en ligne!

Dennis
la source
Comment ça marche? le lambda est-il même appelé?
Sarge Borsch
Le lambda est la soumission réelle (fonction). Tout le reste est juste du code qui doit être exécuté avant que le lambda soit appelé.
Dennis
3

QBasic, 229 octets

LINE INPUT s$
FOR i=1TO LEN(s$)
c$=MID$(s$,i,1)
IF"@"<c$AND"[">c$THEN
IF u THEN MID$(s$,u,1)=c$:MID$(s$,i,1)=u$
u=-i*(u=0)
u$=c$
ELSEIF"`"<c$AND"{">c$THEN
IF l THEN MID$(s$,l,1)=c$:MID$(s$,i,1)=l$
l=-i*(l=0)
l$=c$
END IF
NEXT
?s$

Stratégie

Nous parcourons la chaîne d'entrée. Lorsque nous rencontrons une lettre majuscule, nous la stockons et sa position. La deuxième fois que nous rencontrons une lettre majuscule, nous utilisons ces valeurs stockées pour l'échanger avec la précédente. Même chose pour les minuscules.

(J'étais sur le point de publier une version un peu plus longue qui utilisait un tableau, car je pensais que les chaînes QBasic étaient immuables. Puis, je suis tombé sur le fait que MID$(strng$, index, length) = replacement$ fonctionne parfaitement. Vivez et apprenez.)

Ungolfed + a commenté

LINE INPUT text$

FOR i = 1 TO LEN(text$)
  char$ = MID$(text$, i, 1)
  IF "A" <= char$ AND "Z" >= char$ THEN
    ' Uppercase
    IF upperIndex = 0 THEN
      ' This is the first of a pair of uppercase letters
      ' Store the letter and its index for later
      upperLetter$ = char$
      upperIndex = i
    ELSE
      ' This is the second of a pair of uppercase letters
      ' Put it at the position of the previous uppercase letter
      ' and put that letter at this letter's position
      MID$(text$, upperIndex, 1) = char$
      MID$(text$, i, 1) = upperLetter$
      upperIndex = 0
    END IF
  ELSEIF "a" <= char$ AND "z" >= char$ THEN
    ' Lowercase
    IF lowerIndex = 0 THEN
      ' This is the first of a pair of lowercase letters
      ' Store the letter and its index for later
      lowerLetter$ = char$
      lowerIndex = i
    ELSE
      ' This is the second of a pair of lowercase letters
      ' Put it at the position of the previous lowercase letter
      ' and put that letter at this letter's position
      MID$(text$, lowerIndex, 1) = char$
      MID$(text$, i, 1) = lowerLetter$
      lowerIndex = 0
    END IF
  END IF
NEXT i

PRINT text$
DLosc
la source
2

C ++ 11 (GCC), 154 149 octets

#include<algorithm>
[](std::string s){int*p,u,l=u=-1;for(auto&c:s)(c|32)-97<26U?p=&(c&32?u:l),~*p?(std::swap(c,s[*p]),*p=-1):*p=&c-&s[0]:0;return s;}
vaultah
la source
1
Vous devriez aussi #include<string>soit passer à C ++ 14 et déclarer un lambda générique [](auto s)et supposer sêtre de std::string. En outre, la déclaration [](auto&s)vous évite de renvoyer la chaîne, car il est permis de modifier les arguments d'entrée afin qu'ils servent de sortie.
Karl Napf
2

Qbasic, 436 408 octets

LINE INPUT a$:b=len(a$):FOR a=1TO b:t$=MID$(a$,a,1)
IF"@"<t$AND"[">t$THEN
b$=b$+"U":u$=u$+t$
ELSEIF"`"<t$AND"{">t$THEN
b$=b$+"L":l$=l$+t$
ELSE b$=b$+t$
END IF:NEXT
FOR x=1TO b STEP 2:g$=g$+MID$(u$,x+1,1)+MID$(u$,x,1):h$=h$+MID$(l$,x+1,1)+MID$(l$,x,1):NEXT
FOR x=1TO b:t$=MID$(b$,x,1)
IF"U"=t$THEN
u=u+1:z$=z$+MID$(g$,u,1)
ELSEIF"L"=t$THEN l=l+1:z$=z$+MID$(h$,l,1)
ELSE z$=z$+t$
END IF:NEXT:?z$

Sauvegardé d'un octet grâce à DLosc. En a sauvé plusieurs autres en modifiant le traitement des caractères autres que des lettres.

Cela consiste essentiellement en trois parties:

  • Fractionner l'entrée en 3 chaînes (majuscules, minuscules et une carte (contenant également les autres caractères))
  • Retourner les lettres majuscules et minuscules
  • Utiliser la carte pour (re) construire la sortie.

Une explication plus détaillée (notez qu'il s'agit d'une version antérieure du code, mais le principe s'applique toujours):

' --- Part I: Reading the input
LINE INPUT a$
'This FOR loop takes one character at a time
b=len(a$):FOR a=1TO b
' And checks in what category the character belongs
t$=MID$(a$,a,1):SELECT CASE t$
' For each group, char t$ is added to that group (u$ for uppercase, 
' l$ for lowercase. The map in b$ is updated with a U or L on this index,
' or with the non-letter char t$.
CASE"A"TO"Z":b$=b$+"U":u$=u$+t$
CASE"a"TO"z":b$=b$+"L":l$=l$+t$
CASE ELSE:b$=b$+t$
END SELECT:NEXT

' --- Part II: Swapping within case-groups
' Loop through u$ and l$ twp chars at a time, and add those chunks in reverse order
' to g$ and h$. Because mid$ doesn't fail past the end of a string (but returns ""), 
' this automatically compensates for odd-length groups.
FOR x=1TO b STEP 2:g$=g$+MID$(u$,x+1,1)+MID$(u$,x,1):h$=h$+MID$(l$,x+1,1)+MID$(l$,x,1):NEXT

' --- Part III: Read the map to put it all back together
FOR x=1TO b:t$=MID$(b$,x,1)
' See what group was in this spot, then read the next char from the flipped string.
' This keeps an index on those strings for the next lookup.
IF t$="U"THEN
u=u+1:z$=z$+MID$(g$,u,1)
ELSEIF t$="L"THEN l=l+1:z$=z$+MID$(h$,l,1)
' The map contains a non-letter char, just drop that in
ELSE z$=z$+t$
' And finally,display the end result.
END IF:NEXT:?z$
Steenbergh
la source
2

PHP, 108 93 83 octets

<?=preg_replace([$a="/([a-z])([^a-z]*)([a-z])/",strtoupper($a)],"$3$2$1",$argv[1]);

Version précédente (93 octets)

<?=preg_replace(["/([a-z])([^a-z]*)([a-z])/","/([A-Z])([^A-Z]*)([A-Z])/"],"$3$2$1",$argv[1]);

Merci à @ user59178 de me rappeler que les preg_replace()tableaux de chaînes peuvent être utilisés comme arguments.


La réponse originale (108 octets)

$f=preg_replace;echo$f("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",
$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));

Le code est emballé ici pour s'adapter à l'espace disponible.
Il peut être exécuté à partir de la ligne de commande:

$ php -d error_reporting=0 -r '$f=preg_replace;echo$f("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));' 'lLEhW OroLd!'

Une version plus courte de 1 octet est possible sur PHP 7 en compressant l'attribution de l' $fintérieur de son premier appel:

echo($f=preg_replace)("/([a-z])([^a-z]*)([a-z])/",$r="$3$2$1",
$f("/([A-Z])([^A-Z]*)([A-Z])/",$r,$argv[1]));

Les deux solutions, avec des cas de test et des versions non golfées, sont disponibles sur Github .

axiac
la source
1
preg_replacepeut prendre toute une série de remplacements pour que vous n’ayez besoin que d’un seul appel. De plus, il est plus court à utiliser <?=que echo. Avec ceux-ci, il est simple d'obtenir votre réponse à 93 octets.
user59178
Vous avez raison à propos de preg_replace(). Je l'ai oublié. Je n'aime pas <?=(à mon avis, cela <?ne fait pas partie du langage, ce n'est qu'un marqueur) et j'aime écrire de courts programmes d'une ligne pouvant être exécutés à partir de la ligne de commande php -r. Mais pour les besoins du code golf, vous avez encore raison. Je peux économiser 1 octet en utilisant <?=.
axiac
1

Mathematica, 96 octets

s[#,r="([a-z])(.*?)([a-z])"]~(s=StringReplace[#,RegularExpression@#2->"$3$2$1"]&)~ToUpperCase@r&

Une réponse de Leo's Retina , qui utilise des expressions régulières.

Greg Martin
la source
Honnêtement, je suis surpris que mathematica ne soit pas construit pour cela. Je veux dire, si "Quand est le dimanche de Pâques", "Quand est le coucher du soleil" et "Quelle est la forme de la France" deviennent intégrés, celui-ci devrait l'être aussi!
Sagiksp
1

Python 2 , 124 octets

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

Pas aussi court que ma solution basée sur regex , mais je pense que c'est toujours intéressant.

Essayez-le en ligne!

Dennis
la source
1

Haricot , 83 octets

Hexdump:

00000000 26 53 d0 80 d3 d0 80 a0 5d 20 80 0a a1 81 81 00  &SÐ.ÓÐ. ] ..¡...
00000010 23 81 01 20 80 0a a1 81 81 02 23 81 01 a8 db c1  #.. ..¡...#..¨ÛÁ
00000020 ad da dd a9 a8 db de c1 ad da dd aa bf a9 a8 db  .ÚÝ©¨ÛÞÁ.Úݪ¿©¨Û
00000030 c1 ad da dd 29 a4 b3 a4 b2 a4 31 a8 db e1 ad fa  Á.ÚÝ)¤³¤²¤1¨Ûá.ú
00000040 dd a9 a8 db de e1 ad fa dd aa bf a9 a8 db e1 ad  Ý©¨ÛÞá.úݪ¿©¨Ûá.
00000050 fa dd 29                                         úÝ)
00000053

JavaScript équivalent:

a.replace(/([A-Z])([^A-Z]*?)([A-Z])/g,'$3$2$1').replace(/([a-z])([^a-z]*?)([a-z])/g,'$3$2$1')

Explication:

Prenant implicitement la première ligne d'entrée non formatée comme a(car les nouvelles lignes ne peuvent pas faire partie d'une chaîne embrouillée), et génère implicitement une chaîne non embrouillée en remplaçant séquentiellement les paires majuscules, puis minuscules.

Essayez la démo ici.

Essayez la suite de tests ici.

Patrick Roberts
la source
1

Ruby, 81 octets

puts f=->(i,s){i.gsub /([#{s})([^#{s}*)([#{s})/,'\3\2\1'}[f[$*[0],'a-z]'],'A-Z]']
axiac
la source
1

JavaScript (ES6), 80 octets

Basé sur la réponse de Leo à la rétine .

s=>eval("s"+(r=".replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')")+r.toLowerCase())

Cela fonctionne car les seuls caractères majuscules du code .replace(/([A-Z])([^A-Z]*)([A-Z])/g,'$3$2$1')sont Aet Z, utilisés pour décrire les plages de caractères. C’est précisément ce que nous devons transformer en minuscules pour pouvoir traiter le second passage.

Cas de test

Arnauld
la source
En fait, cela ressemble beaucoup à la réponse de Dennis à Python .
Arnauld
1

ES6 155 - 195 octets

Je sais qu'il y a déjà une meilleure réponse, mais je voulais essayer sans regex. Celui-ci fonctionne également sur la ponctuation, mais cela semble violer le (^_^)test. Dans ce cas, j'ai une autre c()fonction, donnée ci-dessous.

f=(s)=>{d={};s=[...s];for(i in s){b=s[i];for(j in s)if(i<j&!d[i]&c(s[j])==c(b)){d[j]=1;s[i]=s[j];s[j]=b;break}}return s.join('')}
c=c=>~(c.charCodeAt()/32)

f("M I'o DaG") //> I'M a GoD
f("(^_^)")     //> )_^^(

c=c=>((c!=c.toUpperCase())<<1|c!=c.toLowerCase())||c.charCodeAt()

f("M I'o DaG") //> I'M a GoD
f("(^_^)")     //> (^_^)

Explication

f=(s)=>{
    d={};        //list of indexes already swapped
    s=[...s];        //string to array, stolen from above ES6 answer
    for(i in s){
        b=s[i];        //keep a note of what we are swapping
        for(j in s)        //iterate over the array again
            if( i<j & !d[i] & c(s[j])==c(b) ){
                        //only pay attention after we pass i'th
                        //only swap if this char hasn't been swapped
                        //only swap if both chars in same 'category'
                d[j]=1;        //note that the latter char has been swapped
                s[i]=s[j];
                s[j]=b;
                break        //avoid swapping on the same 'i' twice
            }
    }
    return s.join('')        //return as string
}
M3D
la source
1

Perl 6 , 56 octets

{for "A".."Z","a".."z" ->@c {s:g/(@c)(.*?)(@c)/$2$1$0/}}

Prend une variable de chaîne en tant qu'argument et la modifie sur place de sorte que, après avoir appelé le lambda, la variable contienne le résultat.

Plus long que ce serait en Perl, parce que:

  • La nouvelle syntaxe des expressions rationnelles est plus détaillée, par exemple, l'écriture des classes de caractères ressemblerait à celle <[A..Z]>de [A-Z].
  • Les expressions rationnelles sont un code source de première classe analysé lors de la compilation, et une chaîne ne peut y être interpolée au moment de l'exécution que si elle consiste en un subregex autonome (autrement dit, vous ne pouvez pas interpoler une chaîne dans une classe de caractères).
  • Explict EVAL, ce qui permettrait plus de flexibilité, nécessite le use MONKEY-SEE-NO-EVAL;pragma hostile au golf .

Du côté positif, un tableau dans une @variable peut être référencé directement dans une expression rationnelle et est traité comme une alternance.


Perl 6 , 65 octets

{reduce ->$_,@c {S:g/(@c)(.*?)(@c)/$2$1$0/},$_,"A".."Z","a".."z"}

Version fonctionnelle (renvoie le résultat comme valeur de retour du lambda).

smls
la source
1

R, 343 octets

Terriblement maladroite solution R:

f <- function(x) {
        y=unlist(strsplit(x,""))
        z=data.frame(l=ifelse(y %in% letters,0,ifelse(y %in% LETTERS,1,2)),s=y)
        l <- list(which(z$l==0),which(z$l==1))
        v <- unlist(l)
        for(j in 1:2) for (i in seq(1,ifelse(length(l[[j]])%%2==1,length(l[[j]])-2,length(l[[j]])-1),2)) l[[j]][i:(i+1)] <- rev(l[[j]][i:(i+1)])
        z[v,] <- z[unlist(l),]
        return(z$s)
    }

f("D's mroyr, Ivam. I'e faardi I act'n od htta.")

# [1] I ' m   s o r r y ,   D a v e .   I ' m   a f r a i d   I   c a n ' t   d o   t h a t .
compter
la source
1

Python 2, 181 octets

Beaucoup plus long que prévu, mais quand même:

def F(s):
 for l in[i for i,c in enumerate(s)if c.isupper()],[i for i,c in enumerate(s)if c.islower()]:
  for a,b in zip(l[0::2],l[1::2]):s=s[:a]+s[b]+s[a+1:b]+s[a]+s[b+1:]
 print s

Cette première crée deux listes: l’un des index des majuscules et l’autre pour les minuscules. Chacune de ces listes est bouclée par paires d'index et les caractères de ces index sont permutés.

Je vais jouer au golf demain , mais pour le moment, il est temps de dormir .

Daniel
la source
1

Pip , 28 octets

Y[XLXU]aRy.`.*?`.y{Sa@0a@va}

Prend l'entrée en tant qu'argument de ligne de commande. Essayez-le en ligne!

Explication

C'est une solution de regex, utilisant les variables de regex intégrées XL(lettres minuscules `[a-z]`) et XU(lettres majuscules `[A-Z]`).

                              a is 1st cmdline arg; v is -1 (implicit)
Y[XLXU]                       Yank a list containing XL and XU into y
         y.`.*?`.y            Concatenate y, `.*?`, and y itemwise, giving this list:
                              [`[a-z].*?[a-z]`; `[A-Z].*?[A-Z]`]
       aR                     In a, replace matches of each regex in that list...
                  {        }  ... using this callback function:
                   Sa@0a@v     Swap the 0th and -1st characters of the match
                          a    and return the resulting string
                              Print (implicit)

Lorsque le deuxième argument de Rest une liste, les remplacements sont effectués en série; ainsi, le remplacement minuscule et le remplacement majuscule n'interfèrent pas l'un avec l'autre.

DLosc
la source
1

AWK , 121 129 octets

BEGIN{FS=OFS=""}{for(a=1;a<=NF;a++){if($a~/[A-Z]/?U>0?p=U+(U=0):0*(U=a):$a~/[a-z]/?L>0?p=L+(L=0):0*(L=a):0>0){t=$a;$a=$p;$p=t}}}1

Essayez-le en ligne! Remarque: La liaison a 8 octets supplémentaires pour permettre une entrée multiligne.

L'utilisation est assez typique, mais nécessite une version AWKacceptant une chaîne vide comme séparateur de champs (la plupart des versions de gawkmais je suis à peu près sûr que l'original AWKéchouerait :()

C'est très simple car il suffit d'itérer chaque caractère et de vérifier s'il a déjà été trouvé. Si tel est le cas, il permute les caractères et réinitialise l'index vérifié. Pour ce qui est de l’apprentissage, je n’avais jamais utilisé une déclaration de mission dans une déclaration de mission dansAWK auparavant. Pour une raison quelconque, cela ne s'était jamais produit. :)

Je pourrais peut-être raser quelques octets en disant d'affecter OFS et FS en dehors d'un BEGINbloc via une affectation de ligne de commande ou similaire, mais c'est "plus propre" de cette façon.

L'ajout du lien TIO m'a montré que j'avais une erreur de transcription nécessitant 8 octets de réparation :( (j'ai omis 0*(U=a):)

Robert Benson
la source
1

C (gcc) , 212 206 octets

#define I(a,b)if(S[j=i]>=a&S[i]<-~b){for(;S[++j]<a|S[j]>b;);j<l?s[i]=S[j],s[j]=S[i]:0;}
i,j,l;f(char*S){char*s=calloc(l=-~strlen(S),1);for(i=~0;++i<strlen(S);)if(!s[i]){s[i]=S[i];I(65,90)I(97,'z')}puts(s);}

Essayez-le en ligne!

Jonathan Frech
la source
@ceilingcat Merci.
Jonathan Frech
1

Stax , 18 octets

âß:}\]ó☺æ■jφ╛jz/Φi

Exécuter et déboguer

L'approche générale est basée sur les regex.

  • Deux fois faire:
  • Trouver tous les résultats pour [a-z].*?[a-z] .
  • Échangez le premier et le dernier caractère des matchs.
  • Inverser le cas.
récursif
la source
1

R , 223 163 octets 148 octets

EDIT: -60 octets en implémentant une boucle for

EDIT: -15 octets de Giuseppe

u=utf8ToInt(scan(,''));for(i in c(65,97)){l=which(u%in%i:(i+25));x=sum(l|1)%/%2;u[l[1:(x*2)]]=u[c(matrix(l,2)[2:1,1:x])]};cat(intToUtf8(u,T),sep="")

Essayez-le en ligne!

Fonctionne en testant si le caractère est en minuscule ou en majuscule, les place dans une matrice, inverse la matrice pour extraire les valeurs dans un format échangé. Puis sortie avec cat. Essayez-le en ligne scan(,'')si le code comporte plus d'une ligne, d'où les points-virgules de la ligne de code.

Sumner18
la source
J'obtiens 168 sur votre lien, mais ce golf est à 163
Giuseppe
Et cela nous amène à 162.
Giuseppe
cela fonctionne probablement; lex violon est un peu malin, mais il fallait aussi m=matrix4 octets pour s'en débarrasser .
Giuseppe
Qu'en est-il du scan(,'')problème? Et en réduisant le "lLEhW OroLd!" dans TIO scan(,'')ou un autre moyen d'obtenir une contribution?
Sumner18
0

Java 7, 117 octets

String c(String s){String x="([a-z])(.*?)([a-z])",y="$3$2$1";return s.replaceAll(x,y).replaceAll(x.toUpperCase(),y);}

EDIT: Je viens de remarquer que j'ai une réponse similaire à celle de Retina de @Leo , même si j'y ai réfléchi indépendamment.

Ungolfed:

String c(final String s) {
  String x = "([a-z])(.*?)([a-z])",
         y = "$3$2$1";
  return s.replaceAll(x, y).replaceAll(x.toUpperCase(), y);
}

Code de test:

Essayez ici.

class M{
  static String c(String s){String x="([a-z])(.*?)([a-z])",y="$3$2$1";return s.replaceAll(x,y).replaceAll(x.toUpperCase(),y);}

  public static void main(String[] a){
    System.out.println(c("lLEhW OroLd!"));
    System.out.println(c("rpGOZmaimgn uplRzse naC DEoO LdGf"));
    System.out.println(c("eIt uqHKC RBWOO xNf ujPMO SzRE HTL EOvd yAg"));
    System.out.println(c("NraWgCi: Nsas-eNEiTIsev rNsiTG!!"));
    System.out.println(c("(^_^)"));
    System.out.println(c("AWCTY HUOS RETP"));
    System.out.println(c("hwn oeesd acsp nawyya"));
    System.out.println(c("SpMycaeIesKyBorekn"));
    System.out.println(c("D's mroyr, Ivam. I'e faardi I act'n od htta."));
  }
}

Sortie:

hELlO WorLd!
prOGRamming puzZles anD COdE GoLf
tHe quICK BROWN fOx juMPS OvER THE LAzy dOg
WarNiNg: Case-sENsITive sTriNG!!
(^_^)
WATCH YOUR STEP
who needs caps anyway
MySpaceKeyIsBroken
I'm sorry, Dave. I'm afraid I can't do that.
Kevin Cruijssen
la source