Trocar letras e dígitos

14

Dada uma sequência de entrada contendo apenas caracteres ASCII alfanuméricos e iniciando com uma letra, troque cada letra executada pela digitação seguinte.

Uma corrida é uma sequência de letras ou dígitos consecutivos. Observe que, no caso em que a sequência de entrada termina com uma sequência de letras, essa execução é deixada intocada.

Exemplo passo a passo

Por exemplo, dada a sequência de entrada uV5Pt3I0:

  1. Execuções separadas de letras e de dígitos: uV 5 Pt 3 I 0
  2. Identifique pares de execuções: (uV 5) (Pt 3) (I 0)
  3. Troque pares de execuções: (5 uV) (3 Pt) (0 I)
  4. Concatenar: 5uV3Pt0I

Exemplos

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

Isso é então a resposta mais curta em bytes vence. As explicações são incentivadas.

Jim
fonte

Respostas:

9

Geléia , 9 bytes

~ṠŒg⁸ṁṭ2/

Experimente online!

Como 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
fonte
15

Retina , 15 bytes

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

Isso substitui o regex (\D+)(\d+)por$2$1 . Vamos detalhar se você não sabe o que isso significa.

O \Dmeio 'corresponde a qualquer coisa que não seja um número'. \dsignifica 'combinar tudo o que é um número'. O +sinal significa 'igualar isso pelo menos uma vez, mas tente igualá-lo quantas vezes possível'. Os colchetes definem um grupo. O primeiro grupo é (\D+)e o segundo é(\d+)

Na segunda linha, dizemos que queremos colocar o que foi correspondido pelo segundo grupo, seguido pelo que foi correspondido pelo primeiro grupo. Isso efetivamente troca as letras e dígitos.

Experimente online!

Okx
fonte
7

Haskell , 58 56 bytes

Graças a @Laikoni por reduzir 2 bytes

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

Experimente online!

Ungolfed:

f "" = ""
f string | (letters, afterLetters) <- span (> '9') string
         , (numbers, afterNumbers) <- span (< ':') afterLetters
         = numbers ++ letters ++ f afterNumbers
Julian Wolf
fonte
Salve dois bytes com (a,(b,y))<-span(<':')<$>span(>'9')s.
Laikoni
1
Economize ainda mais com (a,(b,y):_)<-lex<$>span(>'9')s: Experimente on-line!
Laikoni 5/07
@Laikoni: Obrigado pela dica! Eu não sou muito claro sobre como lexfunciona, então vou me abster de incluir isso por enquanto. De qualquer forma, é bom saber que há algo parecido no Prelude
Julian Wolf
7

JavaScript (ES6), 34 bytes

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

Tente

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>

Shaggy
fonte
6

Pitão , 15 bytes

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

Explicação

     :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

Conjunto de teste .

Freira Furada
fonte
6

Python 2 , 49 bytes

Todas as soluções não regex que tentei foram mais longas. : P

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

Experimente online!

totalmente humano
fonte
6

Japt (v2.0a0), 16 bytes

q/(\d+/ ò mw c q

Teste online!

Nota: este é um alfa instável; portanto, se esse link for quebrado, você poderá usar uma versão um pouco mais longa na v1.4.4: Teste on-line!

Explicação

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
fonte
Estava tentando descobrir se havia uma maneira de fazer isso ò.
Shaggy
5

CJam , 32 30 28 bytes

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

CJam não tem regex e não "divide em dígitos e letras" ou outros enfeites, então isso foi meio doloroso.

Experimente online!

Explicação

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 negócios
fonte
4

Gema , 11 caracteres

<L><D>=$2$1

Exemplo de execução:

bash-4.4$ gema '<L><D>=$2$1' <<< 'Em5sA55Ve777Rien'
5Em55sA777VeRien
homem a trabalhar
fonte
Tão ... curto. Quero dizer, não é uma linguagem de golfe e apenas 11? Uau.
Erik the Outgolfer
Sim, mas apenas para tarefas que não exigem tocar na mesma entrada duas vezes. Então se torna um pesadelo. ☹
manatwork
Gema encontrado através de um de seus outros posts ... linguagem legal. Quão obscuro você diria que Gema é?
Jonah
@ Jonah, eu diria que sua única parte obscura é o domínio. Embora isso seja parcialmente porque o recurso está sub-documentado. Caso contrário, o idioma é uma coleção de recursos excelentes, mas dolorosamente limitados. (Por exemplo, as rochas reconhecedores, mas seria muito mais poderosa se poderia ser combinados como as classes de personagens expressão regular.)
manatwork
Quão popular era o gema nos anos 90? e possui contrapartes / concorrentes modernos? você o usa para o trabalho ou apenas o encontra por diversão?
Jonah
3

Java 8, 38 bytes

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

Não há muito a explicar. Usa o mesmo método da resposta Retina da @Okx , que não pode ser mais curta em Java.

Experimente aqui.

Kevin Cruijssen
fonte
2

Japonês, 18 bytes

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

Teste-o

Shaggy
fonte
Você pode adicionar a explicação?
Jim
@ Jim, é apenas uma porta da minha solução JS (transpiles Japt para JS), o que deve ser bastante autoexplicativo. Caso contrário, consulte a explicação na solução Retina da Okx; os dois fazem exatamente a mesma coisa.
Shaggy
4
??? @ Downowner: forneça feedback.
Shaggy
@ Shaggy, você mesmo disse, é basicamente copiar e colar a solução da Okx e depois deu um passo adiante para uma linguagem que compila exatamente o mesmo código da sua outra resposta. Por isso, diminuí a votação porque essa não era uma solução única, que não usa nenhuma técnica ou engenhosidade interessante de golfe; antes uma tradução de outra resposta
Downgoat 4/17/17
1
@ Downgoat, obrigado por comentar. No entanto, eu não disse que copiei a solução de Okx, simplesmente direcionei Jim para a explicação. Se você verificar os carimbos de data e hora, verá que eu publiquei minha solução JS quase ao mesmo tempo que o Okx (posso até ter sido o primeiro, mas não consigo ver os carimbos de data e hora exatos no celular). Em seguida, eu enviei minha própria solução para outro idioma, o que acontece o tempo todo aqui, portanto, a menos que você esteja com o voto negativo em todas as portas, não entendo por que você escolheu esta.
Shaggy
2

Sed, 29 bytes

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

Execute com -r.

Usa grupos de captura e os substitui na ordem oposta.

It Guy
fonte
Você pode reduzir [A-Za-z]para [^0-9]. No entanto, você deve contar a sinalização como parte do seu código.
Dennis
Quanto conta a bandeira?
Ele Guy
A diferença entre sed <command>e sed -r <command>, portanto, três bytes.
Dennis
@ Dennis, é a diferença entre sed -f filenamee sed -rf filename(ou entre sed -e 'command'e sed -re 'command'): um único byte.
precisa
Eu perdi a frase-chave (" começando com uma letra ") na pergunta, assim como s/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/giem 48 bytes. Caso contrário, da mesma forma.
precisa
2

Gelatina , 12 bytes

e€ØDŒg⁸ṁs2Ṛ€

Experimente online!

Explicação:

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, o Outgolfer
fonte
2
Você pode adicionar a explicação?
Jim
@Jim Adicionado explanaion.
Erik the Outgolfer
2

PHP, sem regex, 73 bytes

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

Execute como tubo -nRou teste-o online .

demolir

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
fonte
Quero dizer, você pode usar em ~vez dea&
Jörg Hülsermann
1

C #, 71 bytes

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

É uma pena que expressões regulares sejam tão longas em C #.

Experimente online!

Versão completa / formatada:

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
fonte
Você pode adicionar um link ao TIO ?
Jim
@ Jim Done. Geralmente, tenho preguiça de adicioná-lo inicialmente, especialmente enquanto ainda estou procurando por melhorias.
TheLethalCoder
1

Clojure, 104 88 bytes

Oh regex é realmente útil ... enfim ( TIO ):

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

partition-byse divide em execuções consecutivas com base no valor de retorno dessa função, se partition-alldivide em partições de 2 (os pares que trocaremos), map reversereverte-os,flatten se da estrutura de lista aninhada e, finalmente, produzimos uma string. Se partitionfosse usado em vez de partition-alle tivéssemos um número ímpar de pedaços, o último seria descartado.

Original usado detalhado, mas divertido (juxt second first)e, em (set"0123456789")vez de reversee intervalos inteiros ASCII.

#(apply str(flatten(map(juxt second first)(partition-all 2(partition-by(comp not(set"0123456789"))%)))))
NikoNyrh
fonte
Você pode adicionar um link ao TIO e uma explicação?
Jim
1

QuadR , 15 bytes

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

Experimente online!

Explicação roubada descaradamente de Okx :

Isso substitui o regex (\D+)(\d+)por\2\1 . Vamos detalhar se você não sabe o que isso significa.

O \Dmeio 'corresponde a qualquer coisa que não seja um número'. \dsignifica 'combinar tudo o que é um número'. O +sinal significa 'igualar isso pelo menos uma vez, mas tente igualá-lo quantas vezes possível'. Os colchetes definem um grupo. O primeiro grupo é (\D+)e o segundo é(\d+)

Na segunda linha, dizemos que queremos colocar o que foi correspondido pelo segundo grupo, seguido pelo que foi correspondido pelo primeiro grupo. Isso efetivamente troca as letras e dígitos.

Adão
fonte
1

PowerShell , 40 bytes

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

Experimente online!


O PowerShell é ideal para isso, pois suporta a pesquisa e substituição de expressões regulares fora da caixa. Os adereços vão para @Okx para a solução regex.

Jeff Freeman
fonte
1

Pip , 17 bytes

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

Recebe entrada como um argumento de linha de comando. Experimente online!

Explicação

Isso usa a estratégia de substituição de regex padrão, um tanto quanto jogada.

O regex é -C+XL.C+XD, que avalia 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+)`

A substituição é {c.b}uma função de retorno de chamada que concatena o segundo grupo ( c) e o primeiro grupo ( b). (O primeiro argumento para a função a,, contém toda a correspondência.)

Isso é três bytes mais curto que o ingênuo aR`(\D+)(\d+)``\2\1`.

DLosc
fonte
1

brainfuck , 98 bytes

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

Experimente online!

Explicação

Este programa mantém uma fila de letras que ainda não foram exibidas e as produz quando apropriado.

A chave para este programa é >>----[---->+<<<-[>]>]. As três células à direita da célula de entrada começam em zero. Se a entrada for um ponto de código entre 1 e 63 inclusive, isso move o ponteiro um espaço para a direita e coloca a entrada dois espaços à direita dessa nova posição. Caso contrário, o ponteiro move dois espaços para a direita, a célula, um espaço à direita da nova posição, torna-se 63 e o mesmo 63 é subtraído da célula de entrada. Isso divide a entrada em letras (65-122) e 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
fonte
Parabéns por ter uma resposta cerebral, que não é a mais longa das respostas!
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
fonte
Você pode adicionar uma explicação / versão não destruída?
Jim
nada muito a explicar ... detecta NumberString divide em 2 sets e riffles.Plus alguns "Se" condições para trabalhar perfeitamente
J42161217