Scambia le lettere e le cifre


14

Data una stringa di input contenente solo caratteri ASCII alfanumerici e che inizia con una lettera, scambia ogni sequenza di lettere con la sequenza di cifre che segue.

Una corsa è una sequenza di lettere o cifre consecutive. Si noti che nel caso in cui la stringa di input termina con una sequenza di lettere, questa sequenza non viene toccata.

Esempio di walk-through

Ad esempio, data la stringa di input uV5Pt3I0:

  1. Separate serie di lettere e serie di cifre: uV 5 Pt 3 I 0
  2. Identificare coppie di piste: (uV 5) (Pt 3) (I 0)
  3. Scambia coppie di piste: (5 uV) (3 Pt) (0 I)
  4. Concatenare: 5uV3Pt0I

Esempi

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

Questo è quindi vince la risposta più breve in byte. Le spiegazioni sono incoraggiate.

Risposte:


9

Gelatina , 9 byte

~ṠŒg⁸ṁṭ2/

Provalo online!

Come funziona

~ṠŒ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 byte

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

Questo sostituisce la regex (\D+)(\d+)con $2$1. Analizziamolo se non sai cosa significhi.

Il \Dmezzo "corrisponde a tutto ciò che non è un numero". \dsignifica "abbina tutto ciò che è un numero". Il +segno significa "abbina questo almeno una volta ma cerca di abbinarlo il maggior numero di volte possibile". Le parentesi definiscono un gruppo. Il primo gruppo è (\D+)e il secondo è(\d+)

Nella seconda riga diciamo che vogliamo mettere qualunque cosa sia stata abbinata dal secondo gruppo, seguita da qualunque cosa sia stata abbinata dal primo gruppo. Ciò scambia efficacemente la sequenza di lettere e cifre.

Provalo online!


7

Haskell , 58 56 byte

Grazie a @Laikoni per la rasatura di 2 byte

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

Provalo online!

Ungolfed:

f "" = ""
f string | (letters, afterLetters) <- span (> '9') string
         , (numbers, afterNumbers) <- span (< ':') afterLetters
         = numbers ++ letters ++ f afterNumbers

Salva due byte con (a,(b,y))<-span(<':')<$>span(>'9')s.
Laikoni,

1
Risparmia ancora di più con (a,(b,y):_)<-lex<$>span(>'9')s: provalo online!
Laikoni,

@Laikoni: grazie per il suggerimento! Non sono molto chiaro su come lexfunzioni, quindi per ora mi trattengo dal includerlo. In ogni caso, è bello sapere che c'è qualcosa di simile in Prelude
Julian Wolf,

7

JavaScript (ES6), 34 byte

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

Provalo

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

Pyth , 15 byte

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

Spiegazione

     :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 di test .



6

Japt (v2.0a0), 16 byte

q/(\d+/ ò mw c q

Provalo online!

Nota: questo è un alpha instabile, quindi se questo link si interrompe, puoi usare una versione leggermente più lunga in v1.4.4: provalo online!

Spiegazione

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

Stavo cercando di capire se c'era un modo per farlo ò.
Shaggy,

5

CJam , 32 30 28 byte

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

CJam non ha regex e nessuna "suddivisione in cifre e lettere" o quant'altro, quindi è stato doloroso.

Provalo online!

Spiegazione

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 personaggi

<L><D>=$2$1

Esecuzione di esempio:

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

Così corto. Voglio dire, non è un linguaggio da golf e solo 11? Wow.
Erik the Outgolfer,

Sì, ma solo per attività che non richiedono di toccare lo stesso input due volte. Quindi diventa un incubo. ☹
arte

Ho trovato Gema attraverso uno dei tuoi altri post ... bel linguaggio. Quanto oscuro diresti che Gema è?
Giona

@Giona, direi che la sua unica parte oscura è il dominio. Anche se ciò è in parte dovuto al fatto che la funzionalità non è documentata. In caso contrario, la lingua è una raccolta di funzionalità fantastiche ma dolorosamente limitate. (Ad esempio i riconoscitori oscilla, ma sarebbero molto potenti se potessero essere combinati come le classi di caratteri delle espressioni regolari.)
manatwork

quanto era popolare la gema negli anni '90? e ha delle controparti / concorrenti moderni? lo usi per lavoro o lo hai appena trovato per divertimento?
Giona,


2

Japt, 18 byte

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

Provalo


Puoi aggiungere la spiegazione?
Jim

@Jim, è solo una porta della mia soluzione JS (Japt traspila a JS), che dovrebbe essere piuttosto autoesplicativa. In caso contrario, vedere la spiegazione nella soluzione Retina di Okx; entrambi fanno esattamente la stessa cosa.
Shaggy

4
??? @Downvoter: si prega di fornire feedback.
Shaggy

@Shaggy l'hai detto tu stesso, è sostanzialmente copia incolla della soluzione di Okx e poi hai fatto un passo avanti in una lingua che si compila nello stesso identico codice dell'altra tua risposta. Quindi ho effettuato il downvoting perché questa non era una soluzione unica, che non utilizza tecniche di golf o ingegnosità interessanti; piuttosto una traduzione di un'altra risposta
Downgoat,

1
@Downgoat, grazie per i commenti. Tuttavia, non ho detto di aver copiato la soluzione di Okx, ho semplicemente diretto Jim lì per la spiegazione. Se controlli i timestamp, vedrai che ho pubblicato la mia soluzione JS quasi nello stesso momento di Okx (potrei anche essere stato il primo, ma non riesco a vedere i timestamp esatti sui dispositivi mobili). Ho quindi portato il mio propria soluzione ad un altro linguaggio, il che accade tutto il tempo qui così, a meno che non si sta downvoting tutte le porte, non capisco il motivo per cui hai individuato questo fuori.
Shaggy,

2

Sed, 29 byte

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

Esegui con -r.

Utilizza i gruppi di acquisizione e li sostituisce nell'ordine opposto.


È possibile ridurre [A-Za-z]a [^0-9]. Tuttavia, devi contare la bandiera come parte del tuo codice.
Dennis,

Quanto conta la bandiera?
È Guy, il

La differenza tra sed <command>e sed -r <command>, quindi tre byte.
Dennis,

@Dennis, è la differenza tra sed -f filenamee sed -rf filename(o tra sed -e 'command'e sed -re 'command'): un singolo byte.
Toby Speight,

Ho perso la frase chiave (" iniziando con una lettera ") nella domanda, quindi avevo s/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/gi48 byte. Altrimenti, più o meno lo stesso.
Toby Speight,

2

Gelatina , 12 byte

e€ØDŒg⁸ṁs2Ṛ€

Provalo online!

Spiegazione:

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
Puoi aggiungere la spiegazione?
Jim

@Jim Explanion aggiunta.
Erik the Outgolfer,

2

PHP, no regex, 73 byte

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

Esegui come pipe con -nR o testalo online .

abbattersi

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

Voglio dire che puoi usare ~invece dia&
Jörg Hülsermann il


1

C #, 71 byte

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

Solo un peccato che le espressioni regolari siano così lunghe in C #.

Provalo online!

Versione completa / formattata:

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

Puoi aggiungere un link a TIO ?
Jim,

@Jim Done. Di solito sono troppo pigro per aggiungerlo inizialmente, specialmente mentre sono ancora alla ricerca di miglioramenti.
TheLethalCoder il

1

Clojure, 104 88 byte

Oh regex è davvero utile ... comunque ( TIO ):

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

partition-bysi divide in corse consecutive in base al valore restituito di quella funzione, si partition-alldivide in partizioni di 2 (le coppie che scamberemo), le map reverseinverte,flatten elimina la struttura di elenco nidificata e infine generiamo una stringa. Se è partitionstato utilizzato al posto dipartition-all e avessimo un numero dispari di pezzi, l'ultimo sarebbe scartato.

Intervalli usati verbose ma divertenti (juxt second first)e (set"0123456789")invece di reversee ASCII interi.

#(apply str(flatten(map(juxt second first)(partition-all 2(partition-by(comp not(set"0123456789"))%)))))

Puoi aggiungere un link a TIO e una spiegazione?
Jim

1

QuadR , 15 byte

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

Provalo online!

Spiegazione palesemente rubata da Okx :

Questo sostituisce la regex (\D+)(\d+)con\2\1. Analizziamolo se non sai cosa significhi.

Il \Dmezzo "corrisponde a tutto ciò che non è un numero". \dsignifica "abbina tutto ciò che è un numero". Il +segno significa "abbina questo almeno una volta ma cerca di abbinarlo il maggior numero di volte possibile". Le parentesi definiscono un gruppo. Il primo gruppo è (\D+)e il secondo è(\d+)

Nella seconda riga diciamo che vogliamo mettere qualunque cosa sia stata abbinata dal secondo gruppo, seguita da qualunque cosa sia stata abbinata dal primo gruppo. Ciò scambia efficacemente la sequenza di lettere e cifre.


1

PowerShell , 40 byte

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

Provalo online!


PowerShell è abbastanza ideale per questo, visto che supporta regex ricerca e sostituzione immediata. I puntelli vanno su @Okx per la soluzione regex.


1

Pip , 17 byte

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

Accetta input come argomento della riga di comando. Provalo online!

Spiegazione

Questo utilizza la strategia di sostituzione regex standard, un po 'golfata.

La regex è -C+XL.C+XD, che valuta `(?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+)`

La sostituzione è {c.b}una funzione di callback che concatena il secondo gruppo ( c) e il primo gruppo ( b). (Il primo argomento della funzione a, contiene l'intera corrispondenza.)

Questo è di tre byte più corto dell'ingenuo aR`(\D+)(\d+)``\2\1`.


1

Brainfuck , 98 byte

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

Provalo online!

Spiegazione

Questo programma mantiene una coda di lettere che non è stata ancora emessa e le emette quando appropriato.

La chiave di questo programma è >>----[---->+<<<-[>]>]. Le tre celle a destra della cella di input iniziano da zero. Se l'input è un punto di codice compreso tra 1 e 63 incluso, questo sposta il puntatore di uno spazio a destra e posiziona l'input di due spazi a destra di questa nuova posizione. Altrimenti, il puntatore sposta due spazi a destra, la cella di uno spazio a destra della nuova posizione diventa 63 e lo stesso 63 viene sottratto dalla cella di input. Questo divide nettamente l'input in lettere (65-122) e cifre (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

Congratulazioni per avere una risposta brainfuck che non è la più lunga delle risposte!
Jim,


0

Mathematica, 129 byte

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

Puoi aggiungere una spiegazione / versione non golfata?
Jim,

non c'è molto da spiegare ... rileva NumberString si divide in 2 set e riffles.Plus alcune condizioni "If" per funzionare perfettamente
J42161217
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.