Intercambia corridas de letras y dígitos

14

Dada una cadena de entrada que contiene solo caracteres alfanuméricos ASCII y que comienza con una letra, intercambie cada letra con la secuencia de dígitos que sigue.

Una ejecución es una secuencia de letras o dígitos consecutivos. Tenga en cuenta que en el caso en que la cadena de entrada termina con una serie de letras, esta secuencia no se modifica.

Ejemplo de recorrido

Por ejemplo, dada la cadena de entrada uV5Pt3I0:

  1. Tiradas separadas de letras y tiradas de dígitos: uV 5 Pt 3 I 0
  2. Identificar pares de carreras: (uV 5) (Pt 3) (I 0)
  3. Intercambiar pares de carreras: (5 uV) (3 Pt) (0 I)
  4. Concatenar: 5uV3Pt0I

Ejemplos

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

Este es el por lo que gana la respuesta más corta en bytes. Se alientan las explicaciones.

Jim
fuente

Respuestas:

9

Jalea , 9 bytes

~ṠŒg⁸ṁṭ2/

Pruébalo en línea!

Cómo funciona

~ṠŒ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
fuente
15

Retina , 15 bytes

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

Esto reemplaza la expresión regular (\D+)(\d+)con $2$1. Analicemos eso si no sabes lo que eso significa.

Los \Dmedios 'coinciden con cualquier cosa que no sea un número'. \dsignifica "emparejar todo lo que es un número". El +signo significa 'hacer coincidir esto al menos una vez, pero trate de hacerlo tantas veces como sea posible'. Los corchetes definen un grupo. El primer grupo es (\D+)y el segundo es(\d+)

En la segunda línea decimos que queremos poner lo que coincida con el segundo grupo, seguido de lo que coincida con el primer grupo. Esto efectivamente intercambia las corridas de letras y dígitos.

Pruébalo en línea!

Okx
fuente
7

Haskell , 58 56 bytes

Gracias a @Laikoni por reducir 2 bytes

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

Pruébalo en línea!

Sin golf:

f "" = ""
f string | (letters, afterLetters) <- span (> '9') string
         , (numbers, afterNumbers) <- span (< ':') afterLetters
         = numbers ++ letters ++ f afterNumbers
Julian Wolf
fuente
Ahorre dos bytes con (a,(b,y))<-span(<':')<$>span(>'9')s.
Laikoni
1
Ahorre aún más con (a,(b,y):_)<-lex<$>span(>'9')s: ¡ Pruébelo en línea!
Laikoni
@Laikoni: ¡Gracias por el consejo! No tengo muy claro cómo lexfunciona, así que me abstendré de incluir eso por ahora. En cualquier caso, es bueno saber que hay algo así en Prelude
Julian Wolf el
7

JavaScript (ES6), 34 bytes

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

Intentalo

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>

Lanudo
fuente
6

Pyth , 15 bytes

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

Explicación

     :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

Banco de pruebas .

Monja permeable
fuente
6

Python 2 , 49 bytes

Cada solución no regex que probé fue más larga. :PAG

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

Pruébalo en línea!

totalmente humano
fuente
6

Japt (v2.0a0), 16 bytes

q/(\d+/ ò mw c q

¡Pruébalo en línea!

Nota: este es un alfa inestable, por lo que si este enlace se rompe, puede usar una versión un poco más larga en v1.4.4: ¡Pruébelo en línea!

Explicación

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
fuente
Estaba tratando de averiguar si había una manera de hacerlo ò.
Shaggy
5

CJam , 32 30 28 bytes

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

CJam no tiene expresiones regulares ni "división en dígitos y letras" ni nada, así que esto fue un poco doloroso.

Pruébalo en línea!

Explicación

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.
Gato de negocios
fuente
4

Gema , 11 personajes

<L><D>=$2$1

Ejecución de muestra:

bash-4.4$ gema '<L><D>=$2$1' <<< 'Em5sA55Ve777Rien'
5Em55sA777VeRien
hombre trabajando
fuente
Tan corto. Quiero decir, ¿no es un lenguaje de golf y solo 11? Guau.
Erik the Outgolfer
Sí, pero solo para tareas que no requieren tocar la misma entrada dos veces. Entonces se convierte en pesadilla. ☹
manatwork
Encontré a Gema a través de una de tus otras publicaciones ... lenguaje genial. ¿Qué tan oscuro dirías que es Gema?
Jonás
@ Jonás, diría que su única parte oscura es el dominio. Aunque eso se debe en parte a que la función está subdocumentada. De lo contrario, el lenguaje es una colección de características geniales pero dolorosamente limitadas. (Por ejemplo, los reconocedores de rocas, pero serían mucho más poderosa si se podría combinar como las clases regulares de carácter expresión.)
manatwork
¿Qué tan popular fue Gema en los años 90? ¿Y tiene alguna contraparte / competidor moderno? ¿Lo usas para el trabajo o simplemente lo encuentras por diversión?
Jonás
2

Japt, 18 bytes

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

Pruébalo

Lanudo
fuente
¿Puedes agregar la explicación?
Jim
@ Jim, es solo un puerto de mi solución JS (Japt se transfiere a JS), lo que debería explicarse por sí mismo. Si no, vea la explicación en la solución Retina de Okx; los dos hacen exactamente lo mismo.
Shaggy
44
??? @Downvoter: por favor envíe sus comentarios.
Shaggy
@ Shaggy lo dijiste tú mismo, básicamente es copiar y pegar la solución de Okx y luego lo llevaste un paso más allá a un lenguaje que compila exactamente el mismo código que tu otra respuesta. Así que voté en contra porque esta no era una solución única, que no utiliza ninguna técnica de golf interesante o ingenio; más bien una traducción de otra respuesta
Downgoat
1
@Downgoat, gracias por comentar. Sin embargo, no dije que copié la solución de Okx, simplemente dirigí a Jim allí para la explicación. Si verifica las marcas de tiempo, verá que publiqué mi solución JS casi al mismo tiempo que Okx (incluso podría haber sido el primero, pero no puedo ver marcas de tiempo exactas en el móvil). Luego porté mi propia solución a otro idioma, lo que sucede todo el tiempo aquí, así que, a menos que esté votando en contra de todos los puertos, no entiendo por qué ha elegido este.
Shaggy
2

Sed, 29 bytes

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

Corre con -r.

Utiliza grupos de captura y los reemplaza en el orden opuesto.

Chico IT
fuente
Puedes acortar [A-Za-z]a [^0-9]. Sin embargo, debe contar la bandera como parte de su código.
Dennis
¿Cuánto cuenta la bandera?
Es Guy
La diferencia entre sed <command>y sed -r <command>, entonces, tres bytes.
Dennis
@ Dennis, es la diferencia entre sed -f filenamey sed -rf filename(o entre sed -e 'command'y sed -re 'command'): un solo byte.
Toby Speight
Perdí la frase clave (" comenzando con una letra ") en la pregunta, así que tenía s/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/gi48 bytes. De lo contrario, casi lo mismo.
Toby Speight el
2

Jalea , 12 bytes

e€ØDŒg⁸ṁs2Ṛ€

Pruébalo en línea!

Explicación:

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 el Outgolfer
fuente
2
¿Puedes agregar la explicación?
Jim
@Jim Explicación agregada.
Erik the Outgolfer
2

PHP, sin expresiones regulares, 73 bytes

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

Ejecutar como tubería -nRo probarlo en línea .

Descompostura

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
fuente
Quiero decir que puedes usar en ~lugar dea&
Jörg Hülsermann
1

C #, 71 bytes

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

Es una pena que las expresiones regulares sean tan largas en C #.

Pruébalo en línea!

Versión completa / formateada:

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
fuente
¿Puedes agregar un enlace a TIO ?
Jim
@Jim Hecho. Por lo general, soy demasiado flojo para agregarlo inicialmente, especialmente mientras todavía estoy buscando mejoras.
TheLethalCoder
1

Clojure, 104 88 bytes

Oh regex es realmente útil ... de todos modos ( TIO ):

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

partition-byse divide en ejecuciones consecutivas basadas en el valor de retorno de esa función, se partition-alldivide en particiones de 2 (los pares que intercambiaremos), las map reverseinvierte, flattense deshace de la estructura de la lista anidada y finalmente generaremos una cadena. Si partitionse utilizó en lugar departition-all y tuviéramos un número impar de trozos, el último se descartaría.

Original usado detallado pero divertido (juxt second first)y en (set"0123456789")lugar de reverserangos enteros ASCII.

#(apply str(flatten(map(juxt second first)(partition-all 2(partition-by(comp not(set"0123456789"))%)))))
NikoNyrh
fuente
¿Puedes agregar un enlace a TIO y una explicación?
Jim
1

QuadR , 15 bytes

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

Pruébalo en línea!

Explicación robada descaradamente de Okx :

Esto reemplaza la expresión regular (\D+)(\d+)con\2\1. Analicemos eso si no sabes lo que eso significa.

Los \Dmedios 'coinciden con cualquier cosa que no sea un número'. \dsignifica "emparejar todo lo que es un número". El +signo significa 'hacer coincidir esto al menos una vez, pero trate de hacerlo tantas veces como sea posible'. Los corchetes definen un grupo. El primer grupo es (\D+)y el segundo es(\d+)

En la segunda línea decimos que queremos poner lo que coincida con el segundo grupo, seguido de lo que coincida con el primer grupo. Esto efectivamente intercambia las corridas de letras y dígitos.

Adán
fuente
1

PowerShell , 40 bytes

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

Pruébalo en línea!


PowerShell es bastante ideal para esto, ya que admite la búsqueda y sustitución de expresiones regulares de forma inmediata. Los accesorios van a @Okx para la solución regex.

Jeff Freeman
fuente
1

Pip , 17 bytes

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

Toma datos como argumento de línea de comandos. Pruébalo en línea!

Explicación

Esto utiliza la estrategia estándar de reemplazo de expresiones regulares, algo golfizada.

La expresión regular es -C+XL.C+XD, que se evalúa como `(?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+)`

El reemplazo es {c.b}una función de devolución de llamada que concatena el segundo grupo ( c) y el primer grupo ( b). (El primer argumento de la función a, contiene toda la coincidencia).

Esto es tres bytes más corto que el ingenuo aR`(\D+)(\d+)``\2\1`.

DLosc
fuente
1

brainfuck , 98 bytes

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

Pruébalo en línea!

Explicación

Este programa mantiene una cola de letras que aún no se han emitido y las genera cuando corresponde.

La clave de este programa es >>----[---->+<<<-[>]>]. Las tres celdas a la derecha de la celda de entrada comienzan en cero. Si la entrada es un punto de código entre 1 y 63 inclusive, esto mueve el puntero un espacio a la derecha y coloca la entrada dos espacios a la derecha de esta nueva posición. De lo contrario, el puntero se mueve dos espacios a la derecha, la celda un espacio a la derecha de la nueva posición se convierte en 63, y el mismo 63 se resta de la celda de entrada. Esto divide claramente la entrada en letras (65-122) y dígitos (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
fuente
¡Felicitaciones por tener una respuesta mental que no es la más larga de las respuestas!
Jim
0

Mathematica, 129 bytes

(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
fuente
¿Puedes agregar una explicación / versión sin golf?
Jim
no hay mucho que explicar ... detecta que NumberString se divide en 2 juegos y rifles. Además algunas condiciones "If" para que funcionen perfectamente
J42161217