Tukar huruf dan digit

14

Diberikan string input yang hanya berisi karakter ASCII alfanumerik dan dimulai dengan huruf, tukar setiap huruf dengan angka yang diikuti.

Sebuah run adalah urutan huruf berturut-turut atau digit. Perhatikan bahwa dalam kasus di mana string input diakhiri dengan serangkaian huruf, proses ini tidak tersentuh.

Contoh walk-through

Misalnya, diberikan string input uV5Pt3I0:

  1. Pisahkan huruf dan angka: uV 5 Pt 3 I 0
  2. Identifikasi pasangan proses: (uV 5) (Pt 3) (I 0)
  3. Tukar pasangan lari: (5 uV) (3 Pt) (0 I)
  4. Menggabungkan: 5uV3Pt0I

Contohnya

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

Ini adalah sehingga jawaban tersingkat dalam byte menang. Penjelasan didorong.

Jim
sumber

Jawaban:

9

Jelly , 9 byte

~ṠŒg⁸ṁṭ2/

Cobalah online!

Bagaimana itu bekerja

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

Retina , 15 byte

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

Ini menggantikan regex (\D+)(\d+)dengan $2$1. Mari kita jabarkan jika Anda tidak tahu apa artinya itu.

The \D'apa pertandingan yang bukan nomor' berarti. \dberarti 'cocokkan semua yang merupakan angka'. The +tanda berarti 'pertandingan ini setidaknya sekali tetapi mencoba untuk mencocokkan sebanyak mungkin'. Kurung menentukan grup. Kelompok pertama adalah (\D+)dan yang kedua adalah(\d+)

Di baris kedua kita mengatakan bahwa kita ingin meletakkan apa pun yang cocok dengan kelompok kedua, diikuti oleh apa pun yang cocok dengan kelompok pertama. Ini secara efektif menukar menjalankan huruf dan digit.

Cobalah online!

Okx
sumber
7

Haskell , 58 56 byte

Terima kasih kepada @Laikoni karena telah memangkas 2 byte

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

Cobalah online!

Tidak Disatukan:

f "" = ""
f string | (letters, afterLetters) <- span (> '9') string
         , (numbers, afterNumbers) <- span (< ':') afterLetters
         = numbers ++ letters ++ f afterNumbers
Julian Wolf
sumber
Simpan dua byte dengan (a,(b,y))<-span(<':')<$>span(>'9')s.
Laikoni
1
Simpan lebih banyak lagi dengan (a,(b,y):_)<-lex<$>span(>'9')s: Cobalah online!
Laikoni
@Laikoni: Terima kasih atas tipnya! Saya tidak begitu jelas tentang caranyalex kerjanya, jadi saya akan menahan diri untuk tidak memasukkannya sekarang. Bagaimanapun, senang mengetahui bahwa ada sesuatu seperti itu di Prelude
Julian Wolf
7

JavaScript (ES6), 34 byte

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

Cobalah

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
sumber
6

Pyth , 15 byte

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

Penjelasan

     :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 uji .

Biarawati Bocor
sumber
6

Python 2 , 49 byte

Setiap solusi non-regex yang saya coba lebih lama. : P

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

Cobalah online!

benar-benar manusiawi
sumber
6

Japt (v2.0a0), 16 byte

q/(\d+/ ò mw c q

Uji secara online!

Catatan: ini adalah alpha yang tidak stabil, jadi jika tautan ini rusak, Anda dapat menggunakan versi yang sedikit lebih panjang di v1.4.4: Uji secara online!

Penjelasan

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
Produksi ETH
sumber
Sedang berusaha mencari tahu apakah ada cara untuk melakukannya ò.
Shaggy
5

CJam , 32 30 28 byte

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

CJam tidak memiliki regex dan tidak "terbagi menjadi angka dan huruf" atau yang lainnya, jadi ini agak menyakitkan.

Cobalah online!

Penjelasan

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.
Kucing Bisnis
sumber
4

Gema , 11 karakter

<L><D>=$2$1

Contoh dijalankan:

bash-4.4$ gema '<L><D>=$2$1' <<< 'Em5sA55Ve777Rien'
5Em55sA777VeRien
manatwork
sumber
Jadi ... pendek. Maksudku, itu bukan bahasa golf dan hanya 11? Wow.
Erik the Outgolfer
Ya, tetapi hanya untuk tugas yang tidak perlu menyentuh input yang sama dua kali. Maka itu menjadi mimpi buruk. ☹
manatwork
Ditemukan Gema melalui salah satu pos Anda yang lain ... bahasa keren. Seberapa jelas Anda akan mengatakan Gema?
Jonah
@ Jonah, saya akan mengatakan satu-satunya bagian yang tidak jelas adalah domain. Meskipun itu sebagian karena fitur ini tidak terdokumentasi. Kalau tidak, bahasanya adalah kumpulan fitur yang hebat tapi terbatas. (Misalnya, batu pengenal, tetapi mereka akan jauh lebih kuat jika dapat digabungkan seperti kelas karakter ekspresi reguler).
manatwork
seberapa populerkah gema di tahun 90-an? dan apakah ada pesaing / pesaing modern? apakah Anda menggunakannya untuk bekerja atau hanya menemukannya untuk bersenang-senang?
Jonah
3

Java 8, 38 byte

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

Tidak banyak yang bisa dijelaskan. Menggunakan metode yang sama dengan @Okx jawaban Retina , yang tidak bisa lebih pendek di Jawa.

Coba di sini.

Kevin Cruijssen
sumber
2

Japt, 18 byte

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

Menguji

Shaggy
sumber
Bisakah Anda menambahkan penjelasannya?
Jim
@ Jim, ini hanya port dari solusi JS saya (Japt transpiles ke JS), yang seharusnya cukup jelas. Jika tidak, lihat penjelasan dalam solusi Retina Okx; saya berdua melakukan hal yang sama persis.
Shaggy
4
??? @Downvoter: berikan umpan balik.
Shaggy
@ Shaggy Anda mengatakannya sendiri, itu pada dasarnya menyalin pasta dari solusi Okx dan kemudian Anda mengambil satu langkah lebih jauh ke bahasa yang mengkompilasi ke kode yang sama persis dengan jawaban Anda yang lain. Jadi saya kalah karena ini bukan solusi yang unik, yang tidak menggunakan teknik golf yang menarik atau kecerdikan; alih-alih terjemahan dari jawaban lain
Downgoat
1
@Downgoat, terima kasih sudah berkomentar. Namun, saya tidak mengatakan saya menyalin solusi Okx, saya hanya mengarahkan Jim ke sana untuk penjelasan. Jika Anda memeriksa cap waktu, Anda akan melihat bahwa saya memposting solusi JS saya pada waktu yang hampir bersamaan dengan Okx (saya bahkan mungkin yang pertama, tetapi saya tidak dapat melihat cap waktu yang tepat di ponsel). Saya kemudian mem-porting solusi saya sendiri ke bahasa lain, yang terjadi sepanjang waktu di sini jadi, kecuali Anda menurunkan semua port, saya tidak mengerti mengapa Anda memilih yang ini.
Shaggy
2

Sed, 29 byte

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

Jalankan dengan -r.

Menggunakan kelompok yang ditangkap dan menggantinya dalam urutan yang berlawanan.

Itu Guy
sumber
Anda dapat mempersingkat [A-Za-z]menjadi [^0-9]. Namun, Anda harus menghitung bendera sebagai bagian dari kode Anda.
Dennis
Berapa bendera dihitung?
Ini Guy
Perbedaan antara sed <command>dan sed -r <command>, jadi tiga byte.
Dennis
@ Dennis, ini perbedaan antara sed -f filenamedan sed -rf filename(atau antara sed -e 'command'dan sed -re 'command'): satu byte.
Toby Speight
Saya melewatkan frase kunci (" dimulai dengan huruf ") dalam pertanyaan, begitu juga s/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/gipada 48 byte. Kalau tidak, sama saja.
Toby Speight
2

Jelly , 12 byte

e€ØDŒg⁸ṁs2Ṛ€

Cobalah online!

Penjelasan:

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 the Outgolfer
sumber
2
Bisakah Anda menambahkan penjelasannya?
Jim
@ Jim Menambahkan penjelasan.
Erik the Outgolfer
2

PHP, tanpa regex, 73 byte

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

Jalankan sebagai pipa dengan -nRatau uji secara online .

kerusakan

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
sumber
Maksud saya Anda dapat menggunakan ~sebagai gantinyaa&
Jörg Hülsermann
1

C #, 71 byte

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

Sayang ekspresi reguler begitu lama di C #.

Cobalah online!

Versi Lengkap / Terformat:

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
sumber
Bisakah Anda menambahkan tautan ke TIO ?
Jim
@ Jim Selesai. Saya biasanya terlalu malas untuk menambahkannya pada awalnya, terutama saat saya masih mencari perbaikan.
TheLethalCoder
1

Clojure, 104 88 bytes

Oh regex benar-benar berguna ... toh ( TIO ):

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

partition-bymembagi menjadi berturut-turut berjalan berdasarkan nilai kembali fungsi itu, partition-alldibagi menjadi partisi 2 (pasangan kita akan bertukar), map reversemembalikkannya, flattenmenghilangkan struktur daftar bersarang dan akhirnya kita akan menghasilkan string. Jika partitiondigunakan sebagai ganti partition-alldan kami memiliki jumlah ganjil maka yang terakhir akan dibuang.

Asli menggunakan verbose tetapi menyenangkan (juxt second first)dan (set"0123456789")bukannya reversedan rentang integer ASCII.

#(apply str(flatten(map(juxt second first)(partition-all 2(partition-by(comp not(set"0123456789"))%)))))
NikoNyrh
sumber
Bisakah Anda menambahkan tautan ke TIO dan penjelasannya?
Jim
1

QuadR , 15 byte

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

Cobalah online!

Penjelasan yang secara terang-terangan dicuri dari Okx :

Ini menggantikan regex (\D+)(\d+)dengan \2\1. Mari kita jabarkan jika Anda tidak tahu apa artinya itu.

The \D'apa pertandingan yang bukan nomor' berarti. \dberarti 'cocokkan semua yang merupakan angka'. The +tanda berarti 'pertandingan ini setidaknya sekali tetapi mencoba untuk mencocokkan sebanyak mungkin'. Kurung menentukan grup. Kelompok pertama adalah (\D+)dan yang kedua adalah(\d+)

Di baris kedua kita mengatakan bahwa kita ingin meletakkan apa pun yang cocok dengan kelompok kedua, diikuti oleh apa pun yang cocok dengan kelompok pertama. Ini secara efektif menukar menjalankan huruf dan digit.

Adm
sumber
1

PowerShell , 40 byte

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

Cobalah online!


PowerShell sangat ideal untuk ini, karena mendukung regex search-and-replace out of box. Alat peraga pergi ke @Okx untuk solusi regex.

Jeff Freeman
sumber
1

Pip , 17 byte

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

Mengambil input sebagai argumen baris perintah. Cobalah online!

Penjelasan

Ini menggunakan strategi penggantian regex standar, agak golf.

Regex adalah -C+XL.C+XD, yang mengevaluasi ke `(?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+)`

Penggantinya adalah {c.b}, fungsi panggilan balik yang menggabungkan grup kedua ( c) dan grup pertama ( b). (Argumen pertama ke fungsi a,, berisi seluruh kecocokan.)

Ini tiga byte lebih pendek dari yang naif aR`(\D+)(\d+)``\2\1`.

DLosc
sumber
1

brainfuck , 98 byte

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

Cobalah online!

Penjelasan

Program ini memelihara antrian surat yang belum pernah dihasilkan, dan mengeluarkannya jika perlu.

Kunci dari program ini adalah >>----[---->+<<<-[>]>]. Tiga sel di kanan sel input mulai dari nol. Jika input adalah titik kode antara 1 dan 63 inklusif, ini menggerakkan penunjuk satu spasi ke kanan dan menempatkan input dua spasi di sebelah kanan posisi baru ini. Jika tidak, pointer akan memindahkan dua spasi ke kanan, sel satu ruang di sebelah kanan posisi baru menjadi 63, dan 63 yang sama dikurangkan dari sel input. Ini dengan rapi membagi input menjadi huruf (65-122) dan digit (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
sumber
Selamat atas jawaban brainfuck yang bukan jawaban terlama!
Jim
1

Ruby , 31 byte

->x{x.gsub /(\D+)(\d+)/,'\2\1'}

Cobalah online!

Alex
sumber
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)&
J42161217
sumber
Bisakah Anda menambahkan penjelasan / versi yang tidak dikunci?
Jim
tidak banyak yang bisa dijelaskan ... mendeteksi NumberString membagi menjadi 2 set dan riffles. Sertakan beberapa kondisi "Jika" agar bekerja dengan sempurna
J42161217