Échange de lettres et de chiffres

14

Étant donné une chaîne d'entrée contenant uniquement des caractères alphanumériques ASCII et commençant par une lettre, permutez chaque série de lettres avec la série de chiffres qui suit.

Une course est une séquence de lettres ou de chiffres consécutifs. Notez que dans le cas où la chaîne d'entrée se termine par une série de lettres, cette séquence n'est pas modifiée.

Exemple de visite

Par exemple, étant donné la chaîne d'entrée uV5Pt3I0:

  1. Séparez les séries de lettres et les séries de chiffres: uV 5 Pt 3 I 0
  2. Identifiez les paires de pistes: (uV 5) (Pt 3) (I 0)
  3. Échangez des paires de pistes: (5 uV) (3 Pt) (0 I)
  4. Enchaîner: 5uV3Pt0I

Exemples

uV5Pt3I0 -> 5uV3Pt0I
J0i0m8 -> 0J0i8m
abc256 -> 256abc
Hennebont56Fr -> 56HennebontFr
Em5sA55Ve777Rien -> 5Em55sA777VeRien
nOoP -> nOoP

Il s'agit de donc la réponse la plus courte en octets l'emporte. Des explications sont encouragées.

Jim
la source

Réponses:

9

Gelée , 9 octets

~ṠŒg⁸ṁṭ2/

Essayez-le en ligne!

Comment ça fonctionne

~ṠŒg⁸ṁṭ2/  Main link. Argument: s (string)

~          Apply bitwise NOT.
           Bitwise operators attempt to cast to int, so if c is a digit, this
           yields ~int(c), a negative number.
           If c cannot be cast to int, ~ will yield 0.
 Ṡ         Take the sign.
           We've now mapped digits to -1, non-digits to 0.
  Œg       Group consecutive equal elements.
    ⁸ṁ     Mold s as the result, grouping run of digits and runs of non-digits.
       2/  Reduce all pairs of runs by...
      ṭ        tack, appending the first run of the pair to the second run.
Dennis
la source
15

Rétine , 15 octets

(\D+)(\d+)
$2$1

Cela remplace l'expression régulière (\D+)(\d+)par $2$1. Décomposons cela si vous ne savez pas ce que cela signifie.

Le \Dmoyen «correspond à tout ce qui n'est pas un nombre». \dsignifie «correspondre à tout ce qui est un nombre». Le +signe signifie «correspond à cela au moins une fois mais essayez de le faire autant de fois que possible». Les crochets définissent un groupe. Le premier groupe est (\D+)et le second est(\d+)

Dans la deuxième ligne, nous disons que nous voulons mettre tout ce qui a été égalé par le deuxième groupe, suivi de tout ce qui a été égalé par le premier groupe. Cela permute efficacement les cycles de lettres et de chiffres.

Essayez-le en ligne!

Okx
la source
7

Haskell , 58 56 octets

Merci à @Laikoni d'avoir rasé 2 octets

f""=""
f s|(a,(b,y))<-span(<':')<$>span(>'9')s=b++a++f y

Essayez-le en ligne!

Non golfé:

f "" = ""
f string | (letters, afterLetters) <- span (> '9') string
         , (numbers, afterNumbers) <- span (< ':') afterLetters
         = numbers ++ letters ++ f afterNumbers
Julian Wolf
la source
Enregistrez deux octets avec (a,(b,y))<-span(<':')<$>span(>'9')s.
Laikoni
1
Économisez encore plus avec (a,(b,y):_)<-lex<$>span(>'9')s: essayez-le en ligne!
Laikoni
@Laikoni: Merci pour le conseil! Je ne sais pas vraiment comment ça lexmarche, donc je vais m'abstenir de l'inclure pour l'instant. En tout cas, bon de savoir qu'il y a quelque chose comme ça dans Prelude
Julian Wolf
7

JavaScript (ES6), 34 octets

s=>s.replace(/(\D+)(\d+)/g,"$2$1")

Essayez-le

o.innerText=(f=
s=>s.replace(/(\D+)(\d+)/g,"$2$1")
)(i.value="uV5Pt3I0");oninput=_=>o.innerText=f(i.value)
<input id=i><pre id=o>

Hirsute
la source
6

Pyth , 15 octets

ss_Mc:z"(\d+)"3 2

Explication

     :z"(\d+)"3      # Split the input z onto matches of numbers (\d+)
    c           2    # Split the resulting list in pieces of length 2
  _M                 # Reverse each pair
ss                   # Concatenate

Suite de tests .

Leaky Nun
la source
6

Python 2 , 49 octets

Chaque solution non regex que j'ai essayée était plus longue. : P

lambda s:re.sub('(\D+)(\d+)',r'\2\1',s)
import re

Essayez-le en ligne!

totalement humain
la source
6

Japt (v2.0a0), 16 octets

q/(\d+/ ò mw c q

Testez-le en ligne!

Remarque: il s'agit d'un alpha instable, donc si ce lien se brise, vous pouvez utiliser une version légèrement plus longue en v1.4.4: testez- le en ligne!

Explication

q/(\d+/ ò mw c q  : Implicit input              "uV5Pt3I0"
q                 : Split input on
 /(\d+/           :   runs of digits, keeping each run. (This compiles to the regex /(\d+)/g)
                  : This gives                  ["uV","5","Pt","3","I","0",""]
        ò         : Take every pair of items.   [["uV","5"],["Pt","3"],["I","0"],[""]]
          m       : Map each pair by
           w      :   reversing.                [["5","uV"],["3","Pt"],["0","I"],[""]]
             c    : Flatten into one array.     ["5","uV","3","Pt","0","I",""]
               q  : Join into a single string.  "5uV3Pt0I"
                  : Implicit: output result of last expression
ETHproductions
la source
J'essayais de savoir s'il y avait un moyen de le faire ò.
Shaggy
5

CJam , 32 30 28 octets

q{i_64>X\:X^{])[}&c}/]]2/Wf%

CJam n'a pas d'expressions régulières et pas de "division en chiffres et lettres" ou ainsi de suite, donc c'était assez douloureux.

Essayez-le en ligne!

Explication

q      e# Read the input.
{      e# Do the following for every char c:
 i     e#  Get c's codepoint.
 64>   e#  Check if it's greater than 64 (i.e. if it's a letter), pushing 1 or 0.
 X     e#  Push X (variable predefined to 1).
 \:X   e#  Store whether c was a letter or digit into X.
 ^{    e#  If (old X) XOR (new X) is 1:
  ]    e#   Close the current array.
  )    e#   Pull out its last character.
  [    e#   Open a new array.
 }&    e#  (end if)
 c     e#  Turn the codepoint back into a character. This also shoves it into the new array, 
       e#  in case one was opened.
}/     e# (end for)
]      e# Close the final array, since it hasn't been closed yet.
]      e# Wrap the whole stack into an array.
2/     e# Split elements into groups of 2.
Wf%    e# Reverse each group.
       e# Implicitly flatten and print.
Chat d'affaires
la source
4

Gema , 11 personnages

<L><D>=$2$1

Exemple d'exécution:

bash-4.4$ gema '<L><D>=$2$1' <<< 'Em5sA55Ve777Rien'
5Em55sA777VeRien
homme au travail
la source
Si court. Je veux dire, ce n'est pas une langue de golf et seulement 11? Sensationnel.
Erik the Outgolfer
Oui, mais uniquement pour les tâches qui ne nécessitent pas de toucher deux fois la même entrée. Ensuite, cela devient un cauchemar. ☹
manatwork
J'ai trouvé Gema à travers l'un de vos autres articles ... un langage cool. À quel point diriez-vous que Gema est obscure?
Jonah
@ Jonah, je dirais que sa seule partie obscure est le domaine. Bien que ce soit en partie parce que la fonctionnalité est sous-documentée. Sinon, le langage est une collection de fonctionnalités géniales mais douloureusement limitées. (Par exemple, les
outils de
Quelle était la popularité de Gema dans les années 90? et a-t-il des homologues / concurrents modernes? L'utilisez-vous pour le travail ou l'avez-vous simplement trouvé pour le plaisir?
Jonah
3

Java 8, 38 octets

s->s.replaceAll("(\\D+)(\\d+)","$2$1")

Pas grand chose à expliquer. Utilise la même méthode que la réponse Retina de @Okx , qui ne peut pas être plus courte en Java.

Essayez-le ici.

Kevin Cruijssen
la source
2

Japt, 18 octets

r"(%D+)(%d+)""$2$1

Essaye-le

Hirsute
la source
Pouvez-vous ajouter l'explication?
Jim
@Jim, c'est juste un portage de ma solution JS (Japt transpile en JS), ce qui devrait être assez explicite. Sinon, voir l'explication dans la solution de rétine d'Okx; les deux font exactement la même chose.
Shaggy
4
??? @Downvoter: veuillez fournir des commentaires.
Shaggy
@Shaggy vous l'avez dit vous-même, il s'agit essentiellement de copier-coller de la solution d'Okx, puis vous êtes allé plus loin dans une langue qui compile exactement le même code que votre autre réponse. J'ai donc voté contre parce que ce n'était pas une solution unique, qui n'utilise pas de techniques de golf intéressantes ou d'ingéniosité; plutôt une traduction d'une autre réponse
Downgoat
1
@Downgoat, merci pour vos commentaires. Cependant, je n'ai pas dit que j'avais copié la solution d'Okx, j'ai simplement dirigé Jim là-bas pour l'explication. Si vous vérifiez les horodatages, vous verrez que j'ai posté ma solution JS presque en même temps qu'Okx (j'ai peut-être même été le premier, mais je ne peux pas voir les horodatages exacts sur mobile). J'ai ensuite porté ma propre solution dans une autre langue, ce qui arrive tout le temps ici, donc, à moins que vous ne diminuiez tous les ports, je ne comprends pas pourquoi vous avez choisi celui-ci.
Shaggy
2

Sed, 29 octets

s/([^0-9]+)([0-9]+)/\2\1/g

Exécutez avec -r.

Utilise les groupes de capture et les remplace dans l'ordre inverse.

It Guy
la source
Vous pouvez raccourcir [A-Za-z]à [^0-9]. Cependant, vous devez compter le drapeau dans votre code.
Dennis
Combien compte le drapeau?
It Guy
La différence entre sed <command>et sed -r <command>, donc trois octets.
Dennis
@Dennis, c'est la différence entre sed -f filenameet sed -rf filename(ou entre sed -e 'command'et sed -re 'command'): un seul octet.
Toby Speight
J'ai raté la phrase clé (" commençant par une lettre ") dans la question, donc j'ai eu s/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/già 48 octets. Sinon, à peu près la même chose.
Toby Speight
2

Gelée , 12 octets

e€ØDŒg⁸ṁs2Ṛ€

Essayez-le en ligne!

Explication:

e€ØDŒg⁸ṁs2Ṛ€ Accepts a string
eۯD         Check if each char is in ['0'..'9']
    Œg       Split runs of 0s and 1s (respectively letter and digit runs)
      ⁸ṁ     Replace with input, keeping the split
        s2   Get pairs of runs, last left alone if letter run
          Ṛ€ Swap each pair
Erik le Outgolfer
la source
2
Pouvez-vous ajouter l'explication?
Jim
@Jim Ajouté explanaion.
Erik the Outgolfer le
2

PHP, aucune expression régulière, 73 octets

for(;a&$c=$argn[$i++];$p=$c)$c<A?print$c:$s=($p<A?!print$s:$s).$c;echo$s;

Exécuter en tant que pipe avec -nRou tester en ligne .

panne

for(;a&$c=$argn[$i++];  # loop through input
    $p=$c)                  # 2. remember character
    $c<A                    # 1. if digit
        ?print$c            # then print it
        :$s=($p<A           # else if previous character was digit
            ?!print$s           # then print and reset string
            :$s                 # else do nothing
        ).$c;                   # append current character to string
echo$s;                 # print remaining string
Titus
la source
Je veux dire que vous pouvez utiliser à la ~place dea&
Jörg Hülsermann
1

C #, 71 octets

s=>System.Text.RegularExpressions.Regex.Replace(s,@"(\D+)(\d+)","$2$1")

Juste une honte, les expressions régulières sont si longues en C #.

Essayez-le en ligne!

Version complète / formatée:

using System;

class P
{
    static void Main()
    {
        Func<string, string> f = s => System.Text.RegularExpressions.Regex.Replace(s, @"(\D+)(\d+)", "$2$1");

        Console.WriteLine(f("uV5Pt3I0"));
        Console.WriteLine(f("J0i0m8"));
        Console.WriteLine(f("abc256"));
        Console.WriteLine(f("Hennebont56Fr"));
        Console.WriteLine(f("Em5sA55Ve777Rien"));
        Console.WriteLine(f("nOoP"));

        Console.ReadLine();
    }
}
TheLethalCoder
la source
Pouvez-vous ajouter un lien vers TIO ?
Jim
@Jim Done. Je suis généralement trop paresseux pour l'ajouter au départ, surtout pendant que je recherche encore des améliorations.
TheLethalCoder
1

Clojure, 104 88 octets

Oh regex est vraiment pratique ... de toute façon ( TIO ):

#(apply str(flatten(map reverse(partition-all 2(partition-by(fn[i](< 47(int i)58))%)))))

partition-byse divise en exécutions consécutives en fonction de la valeur de retour de cette fonction, partition-allse divise en partitions de 2 (les paires que nous allons échanger), les map reverseinverse, flattense débarrasse de la structure de liste imbriquée et, finalement, nous produirons une chaîne. Si a partitionété utilisé à la place departition-all et que nous avions un nombre impair de morceaux, le dernier serait jeté.

Original utilisé verbeux mais amusant (juxt second first)et (set"0123456789")au lieu de reverseet des plages entières ASCII.

#(apply str(flatten(map(juxt second first)(partition-all 2(partition-by(comp not(set"0123456789"))%)))))
NikoNyrh
la source
Pouvez-vous ajouter un lien vers TIO et une explication?
Jim
1

QuadR , 15 octets

(\D+)(\d+)
\2\1

Essayez-le en ligne!

Explication manifestement volée à Okx :

Cela remplace l'expression régulière (\D+)(\d+)par \2\1. Décomposons cela si vous ne savez pas ce que cela signifie.

Le \Dmoyen «correspond à tout ce qui n'est pas un nombre».\dsignifie «correspondre à tout ce qui est un nombre». le+signe signifie «correspond à cela au moins une fois mais essayez de le faire autant de fois que possible». Les crochets définissent un groupe. Le premier groupe est (\D+)et le second est(\d+)

Dans la deuxième ligne, nous disons que nous voulons mettre tout ce qui a été égalé par le deuxième groupe, suivi de tout ce qui a été égalé par le premier groupe. Cela permute efficacement les cycles de lettres et de chiffres.

Adam
la source
1

PowerShell , 40 octets

$args|%{$_ -replace '(\D+)(\d+)','$2$1'}

Essayez-le en ligne!


PowerShell est assez idéal pour cela, car il prend en charge la recherche et le remplacement regex prêts à l'emploi. Les accessoires vont à @Okx pour la solution regex.

Jeff Freeman
la source
1

Pip , 17 octets

aR-C+XL.C+XD{c.b}

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

Explication

Cela utilise la stratégie standard de remplacement des regex, quelque peu golfée.

Le regex est -C+XL.C+XD, qui évalue à `(?i)([a-z]+)(\d+)`:

   XL       Preset regex variable for lowercase letter: `[a-z]`
  +         Apply + to the regex: `[a-z]+`
 C          Wrap the regex in a capturing group: `([a-z]+)`
-           Apply the case-insensitive flag: `(?i)([a-z]+)`
        XD  Preset regex variable for digit: `\d`
       +    Apply + to the regex: `\d+`
      C     Wrap the regex in a capturing group: `(\d+)`
     .      Concatenate the two regexes: `(?i)([a-z]+)(\d+)`

Le remplacement est {c.b}une fonction de rappel qui concatène le deuxième groupe ( c) et le premier groupe ( b). (Le premier argument de la fonction a,, contient toute la correspondance.)

C'est trois octets de moins que le naïf aR`(\D+)(\d+)``\2\1`.

DLosc
la source
1

brainfuck , 98 octets

,[>>----[---->+<<<-[>]>]>>[.[[-]<]<<[-]+>>]<[[-<<<+>>>]<<<<[-<[<]>[.[-]>]]>[-<+>]>],]<[-]<[<]>[.>]

Essayez-le en ligne!

Explication

Ce programme maintient une file d'attente de lettres qui n'ont pas encore été sorties, et les sort le cas échéant.

La clé de ce programme est >>----[---->+<<<-[>]>]. Les trois cellules à droite de la cellule d'entrée commencent à zéro. Si l'entrée est un point de code compris entre 1 et 63 inclus, cela déplace le pointeur d'un espace vers la droite et place l'entrée deux espaces à droite de cette nouvelle position. Sinon, le pointeur se déplace de deux espaces vers la droite, la cellule un espace à droite de la nouvelle position devient 63, et le même 63 est soustrait de la cellule d'entrée. Cela divise parfaitement l'entrée en lettres (65-122) et en chiffres (48-57).

,[                       Take first input byte and start main loop
  >>                     Move two cells to the right
  ----[---->+<<<-[>]>]   (See above)
  >>                     Move two cells to the right
                         This cell contains the input if it was a digit, and 0 if input was a letter
  [                      If input was a digit:
   .                     Output digit immediately
   [[-]<]                Zero out digit and working cell
   <<[-]+>>              Set flag so we know later that we've output a digit
  ]
  <                      Move one cell left
                         This cell contains 63 if input was a letter, and 0 if input was a digit
  [                      If input was a letter:
   [-<<<+>>>]            Add 63 back to input letter
   <<<<                  Move to flag
   [                     If a digit has been output since the last letter read:
    -                    Clear flag
    <[<]>                Move to start of queue
    [.[-]>]              Output and clear all queued letters
   ]
   >[-<+>]>              Move input to end of queue
  ]
,]                       Repeat until no input remains
<[-]                     Clear flag if present
<[<]>                    Move to start of queue
[.>]                     Output all queued letters
Nitrodon
la source
Félicitations pour avoir une réponse de brainfuck qui n'est pas la plus longue des réponses!
Jim
0

Mathematica, 129 octets

(n=NumberString;l=Length;s=Riffle[a=StringCases[#,n],b=StringSplit[#,n]];If[l@a==0,s=#,If[l@a<l@b,AppendTo[s,b[[-2;;]]]]];""<>s)&
J42161217
la source
Pouvez-vous ajouter une explication / version non golfée?
Jim
rien à expliquer ... détecte NumberString se divise en 2 sets et riffles.Plus quelques conditions "If" afin de fonctionner parfaitement
J42161217