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.

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.

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!


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

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>


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 .



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

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.

4

Gema , 11 caracteres

<L><D>=$2$1

Exemplo de execução:

bash-4.4$ gema '<L><D>=$2$1' <<< 'Em5sA55Ve777Rien'
5Em55sA777VeRien

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


2

Japonês, 18 bytes

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

Teste-o


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.


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

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

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();
    }
}

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

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.



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`.


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

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.