สลับตัวอักษรและตัวเลขหลัก


14

รับสตริงอินพุตที่มีอักขระ ASCII ตัวอักษรผสมตัวเลขและเริ่มต้นด้วยตัวอักษรสลับตัวอักษรแต่ละตัวที่รันด้วยการรันหลักที่ตามมา

การวิ่งคือลำดับของตัวอักษรหรือตัวเลขที่ต่อเนื่องกัน โปรดทราบว่าในกรณีที่สตริงอินพุตลงท้ายด้วยการรันตัวอักษรการรันนี้จะไม่ถูกแตะต้อง

ตัวอย่างการเดินผ่าน

ตัวอย่างเช่นกำหนดสตริงอินพุตuV5Pt3I0:

  1. แยกการวิ่งของตัวอักษรและการวิ่งของตัวเลข: uV 5 Pt 3 I 0
  2. ระบุคู่รัน: (uV 5) (Pt 3) (I 0)
  3. สลับคู่ของการวิ่ง: (5 uV) (3 Pt) (0 I)
  4. concatenate: 5uV3Pt0I

ตัวอย่าง

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

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ คำอธิบายได้รับการสนับสนุน

คำตอบ:


9

เยลลี่ขนาด 9 ไบต์

~ṠŒg⁸ṁṭ2/

ลองออนไลน์!

มันทำงานอย่างไร

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

เรติน่า 15 ไบต์

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

นี้แทนที่ regex ไม่ด้วย(\D+)(\d+) $2$1มาทำลายมันลงถ้าคุณไม่รู้ว่ามันแปลว่าอะไร

\D'อะไรการแข่งขันที่ไม่ได้เป็นจำนวน' หมายถึง \dหมายถึง 'จับคู่ทุกอย่างที่เป็นตัวเลข' +สัญญาณหมายถึง 'ตรงนี้อย่างน้อยหนึ่งครั้ง แต่พยายามที่จะตรงกับมันได้บ่อยเท่าที่เป็นไปได้' วงเล็บกำหนดกลุ่ม กลุ่มแรกคือ(\D+)และที่สองคือ(\d+)

ในบรรทัดที่สองเราบอกว่าเราต้องการที่จะนำสิ่งที่ถูกจับคู่โดยกลุ่มที่สองตามด้วยสิ่งที่ถูกจับคู่โดยกลุ่มแรก สิ่งนี้จะสลับการรันตัวอักษรและตัวเลขอย่างมีประสิทธิภาพ

ลองออนไลน์!


7

Haskell , 58 56 ไบต์

ขอบคุณ @Laikoni สำหรับการตัด 2 ไบต์

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

ลองออนไลน์!

Ungolfed:

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

(a,(b,y))<-span(<':')<$>span(>'9')sบันทึกไบต์ที่สองด้วย
Laikoni

1
ประหยัดมากยิ่งขึ้นด้วย(a,(b,y):_)<-lex<$>span(>'9')s: ลองออนไลน์!
Laikoni

@Laikoni: ขอบคุณสำหรับเคล็ดลับ! ฉันไม่ชัดเจนเกี่ยวกับวิธีการlexทำงานดังนั้นฉันจะละเว้นจากการรวมไว้สำหรับตอนนี้ ไม่ว่าในกรณีใดก็ควรรู้ว่ามีบางอย่างเช่นนั้นในพรีลูด
จูเลียนวูล์ฟ




6

Japt (v2.0a0) ขนาด 16 ไบต์

q/(\d+/ ò mw c q

ทดสอบออนไลน์!

หมายเหตุ: นี่เป็นอัลฟาที่ไม่เสถียรดังนั้นหากการเชื่อมโยงนี้แตกคุณสามารถใช้เวอร์ชันที่ยาวกว่าเล็กน้อยใน v1.4.4: ทดสอบออนไลน์!

คำอธิบาย

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

òได้พยายามที่จะคิดออกว่ามีวิธีที่จะทำมันด้วย
Shaggy

5

CJam , 32 30 28 bytes

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

CJam ไม่มี regex และไม่มี "แยกเป็นตัวเลขและตัวอักษร" หรืออะไรก็ตามดังนั้นมันจึงเจ็บปวด

ลองออนไลน์!

คำอธิบาย

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 ตัวอักษร

<L><D>=$2$1

วิ่งตัวอย่าง:

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

ดังนั้น ... สั้น ฉันหมายความว่าไม่ใช่ภาษากอล์ฟและมีเพียง 11 คนใช่ไหม ว้าว.
Erik the Outgolfer

ใช่ แต่สำหรับงานที่ไม่จำเป็นต้องสัมผัสอินพุตเดียวกันสองครั้ง จากนั้นมันจะกลายเป็นฝันร้าย ☹
จัดการ

พบ Gema ผ่านหนึ่งในโพสต์อื่น ๆ ของคุณ ... ภาษายอดเยี่ยม คุณจะบอกว่า Gema คลุมเครือแค่ไหน?
โยนาห์

@Jonah ฉันจะบอกว่าส่วนที่คลุมเครือเพียงอย่างเดียวคือโดเมน แม้ว่ามันจะเป็นเพียงบางส่วนเพราะคุณสมบัตินั้นด้อยค่าลง ไม่อย่างนั้นภาษาคือชุดของคุณสมบัติที่ยอดเยี่ยม แต่มีข้อ จำกัด อย่างเจ็บปวด (ตัวอย่างเช่นหินของตัวจดจำ แต่จะมีประสิทธิภาพมากถ้าสามารถรวมกันเป็นคลาสอักขระนิพจน์ทั่วไปได้)
manatwork

วิธีที่นิยมคือ gema ใน 90s? และมันมีคู่ / คู่แข่งสมัยใหม่หรือไม่? คุณใช้มันเพื่อทำงานหรือแค่พบมันเพื่อความสนุก?
โยนาห์


2

Japt, 18 ไบต์

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

ทดสอบมัน


คุณสามารถเพิ่มคำอธิบายได้ไหม?
Jim

@ จิมมันเป็นเพียงแค่พอร์ตของโซลูชัน JS ของฉัน (Japt transpiles ถึง JS) ซึ่งควรอธิบายด้วยตนเอง ถ้าไม่เห็นคำอธิบายในโซลูชัน Retina ของ Okx; ฉันทั้งคู่ทำสิ่งเดียวกัน
Shaggy

4
??? @Downvoter: โปรดให้ข้อเสนอแนะ
Shaggy

@Shaggy คุณพูดด้วยตัวเองโดยทั่วไปแล้วมันเป็นการคัดลอกโพสต์ของ Okx แล้วคุณก็เพิ่มอีกหนึ่งขั้นในภาษาที่คอมไพล์รหัสเดียวกันกับคำตอบอื่นของคุณ ดังนั้นฉันจึงลงคะแนนเพราะนี่ไม่ใช่วิธีแก้ปัญหาที่ไม่เหมือนใครซึ่งไม่ได้ใช้เทคนิคการเล่นกอล์ฟที่น่าสนใจหรือความเฉลียวฉลาด ค่อนข้างเป็นการแปลคำตอบอื่น
Downgoat

1
@Downgoat ขอบคุณสำหรับการแสดงความคิดเห็น อย่างไรก็ตามฉันไม่ได้บอกว่าฉันคัดลอกโซลูชันของ Okx ฉันเพียงกำกับ Jim ที่นั่นเพื่อขอคำอธิบาย หากคุณตรวจสอบการประทับเวลาคุณจะเห็นว่าฉันโพสต์โซลูชัน JS ของฉันเกือบจะในเวลาเดียวกับ Okx (ฉันอาจจะเป็นคนแรก แต่ฉันไม่เห็นการประทับเวลาที่แน่นอนบนมือถือ) ฉันพูดถึงวิธีแก้ปัญหาของตัวเองเป็นภาษาอื่นซึ่งเกิดขึ้นตลอดเวลาที่นี่ดังนั้นหากคุณไม่ได้ลงคะแนนในพอร์ตทั้งหมดฉันไม่เข้าใจว่าทำไมคุณจึงแยกภาษานี้ออก
Shaggy

2

Sed, 29 ไบต์

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

รันด้วย -r

ใช้กลุ่มการดักจับและแทนที่พวกมันในลำดับที่ตรงกันข้าม


คุณสามารถร่นไป[A-Za-z] [^0-9]อย่างไรก็ตามคุณต้องนับการตั้งค่าสถานะเป็นส่วนหนึ่งของรหัสของคุณ
Dennis

ค่าสถานะจะนับเป็นเท่าใด
มัน Guy

ความแตกต่างระหว่างsed <command>และsed -r <command>ดังนั้นสามไบต์
Dennis

@Dennis มันเป็นความแตกต่างระหว่างsed -f filenameและsed -rf filename(หรือระหว่างsed -e 'command'และsed -re 'command'): ไบต์เดียว
Toby Speight

ฉันพลาดวลีสำคัญ (" เริ่มต้นด้วยตัวอักษร ") ในคำถามดังนั้นมีs/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/giขนาด 48 ไบต์ มิฉะนั้นมากเหมือนกัน
Toby Speight

2

เยลลี่ 12 ไบต์

e€ØDŒg⁸ṁs2Ṛ€

ลองออนไลน์!

คำอธิบาย:

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
คุณสามารถเพิ่มคำอธิบายได้ไหม?
Jim

@Jim เพิ่มคำอธิบายแล้ว
Erik the Outgolfer

2

PHP, ไม่มี regex, 73 ไบต์

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

ทำงานเป็นท่อที่มี-nRหรือทดสอบออนไลน์

ชำรุด

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

ฉันหมายถึงคุณสามารถใช้~แทนa&
JörgHülsermann


1

C #, 71 ไบต์

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

การแสดงออกปกติที่น่าละอายนั้นมีมานานใน C #

ลองออนไลน์!

เวอร์ชันเต็ม / ฟอร์แมต:

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

คุณสามารถเพิ่มลิงค์ไปยังTIO ได้หรือไม่?
Jim

@Jim เรียบร้อยแล้ว ฉันมักจะขี้เกียจเกินไปที่จะเพิ่มในตอนแรกโดยเฉพาะอย่างยิ่งในขณะที่ฉันยังคงมองหาการปรับปรุงใด ๆ
TheLethalCoder

1

Clojure, 104 88 ไบต์

โอ้ regex มีประโยชน์จริง ๆ ... ต่อไป ( TIO ):

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

partition-byแยกเป็นการรันที่ต่อเนื่องกันตามค่าตอบแทนของฟังก์ชันนั้นpartition-allแบ่งออกเป็นพาร์ติชั่น2 (คู่ที่เราจะทำการสลับ) map reverseกลับรายการพวกมันflattenกำจัดโครงสร้างลิสต์ที่ซ้อนกันและในที่สุดเราก็จะเอาท์พุทสตริง หากpartitionใช้แทนpartition-allและเรามีจำนวนคี่จำนวนหนึ่งชิ้นสุดท้ายจะถูกยกเลิก

verbose เดิมที่ใช้ แต่สนุก(juxt second first)และ(set"0123456789")แทนreverseและช่วงจำนวนเต็ม ASCII

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

Can you add a link to TIO and an explanation?
Jim

1

QuadR, 15 bytes

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

Try it online!

Explanation blatantly stolen from Okx:

This replaces the regex (\D+)(\d+) with \2\1. Let's break that down if you don't know what that means.

The \D means 'match anything that isn't a number'. \d means 'match everything that is a number'. The + sign means 'match this at least once but try to match it as many times as possible'. The brackets define a group. The first group is (\D+) and the second is (\d+)

In the second line we say that we want to put whatever was matched by the second group, followed by whatever was matched by the first group. This effectively swaps the letter and digit runs.


1

PowerShell, 40 bytes

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

Try it online!


PowerShell เหมาะอย่างยิ่งสำหรับสิ่งนี้เนื่องจากเห็นว่ารองรับการค้นหาและแทนที่ regex อุปกรณ์ประกอบฉากไปที่@Okxเพื่อดูวิธีแก้ปัญหา regex


1

Pip , 17 ไบต์

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

รับอินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง ลองออนไลน์!

คำอธิบาย

สิ่งนี้ใช้กลยุทธ์การเปลี่ยน regex มาตรฐานซึ่งค่อนข้างกอล์ฟ

regex คือ-C+XL.C+XDซึ่งประเมินว่า`(?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+)`

การแทนที่คือ{c.b}ฟังก์ชันการเรียกกลับที่เชื่อมกลุ่มที่สอง ( c) และกลุ่มแรก ( b) (อาร์กิวเมนต์แรกของฟังก์ชันaประกอบด้วยการแข่งขันทั้งหมด)

aR`(\D+)(\d+)``\2\1`นี่คือสามไบต์สั้นกว่าที่ไร้เดียงสา


1

brainfuck , 98 ไบต์

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

ลองออนไลน์!

คำอธิบาย

โปรแกรมนี้เก็บคิวตัวอักษรมากกว่าที่ยังไม่ได้ส่งออกและส่งออกตามความเหมาะสม

>>----[---->+<<<-[>]>]กุญแจสำคัญในการโปรแกรมนี้คือ สามเซลล์ด้านขวาของเซลล์อินพุตเริ่มต้นที่ศูนย์ หากการป้อนข้อมูลเป็นจุดรหัสระหว่าง 1 ถึง 63 สิ่งนี้จะย้ายตัวชี้หนึ่งช่องว่างไปทางขวาและวางช่องว่างสองช่องทางด้านขวาของตำแหน่งใหม่นี้ มิฉะนั้นตัวชี้เลื่อนสองช่องว่างไปทางขวาเซลล์หนึ่งช่องว่างด้านขวาของตำแหน่งใหม่จะกลายเป็น 63 และ 63 ตัวเดียวกันจะถูกลบออกจากเซลล์อินพุต นี่เป็นการแบ่งอินพุตอย่างเป็นตัวอักษร (65-122) และตัวเลข (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

ขอแสดงความยินดีที่มีคำตอบในสมองที่ไม่ยาวที่สุดของคำตอบ!
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)&

Can you add an explanation / ungolfed version?
Jim

nothing much to explain...detects NumberString divides into 2 sets and riffles.Plus some "If" conditions in order to work perfectly
J42161217
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.