Поміняйте місцями пробіли букви та цифри


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. З'єднайте: 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

Це замінює регулярний вираз (\D+)(\d+)з $2$1. Давайте розбиємо це, якщо ви не знаєте, що це означає.

\DЗіставляють все , що не є числом "означає. \dозначає "співставити все, що є числом". В +знак означає "відповідати цьому принаймні один раз , але спробувати відповідати його стільки разів , скільки це можливо. Дужки визначають групу. Перша група є, (\D+)а друга -(\d+)

У другому рядку ми говоримо, що ми хочемо поставити все, що відповідало другій групі, а потім все, що було відповідне першій групі. Це ефективно підміняє літери та цифри.

Спробуйте в Інтернеті!


7

Хаскелл , 58 56 байт

Дякуємо @Laikoni за бриття 2-х байт

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

Спробуйте в Інтернеті!

Безголівки:

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працює, тому я зараз утримуюся від включення цього. У будь-якому випадку, добре знати, що у Прелюдії є щось подібне
Julian Wolf

7

JavaScript (ES6), 34 байти

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

Спробуй це

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

Japt (v2.0a0), 16 байт

q/(\d+/ ò mw c q

Перевірте це в Інтернеті!

Примітка: це нестабільна альфа, тому якщо це посилання перерветься, ви можете використовувати трохи довшу версію в версії 1.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 байт

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

CJam не має регексу і не "розбивається на цифри і букви" чи що-небудь ще, тому це було наче болісно.

Спробуйте в Інтернеті!

Пояснення

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

Гема , 11 символів

<L><D>=$2$1

Проба зразка:

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

Отже ... короткий. Я маю на увазі, це не мова про гольф, а просто 11? Ого.
Ерік Аутгольфер

Так, але лише для завдань, які не вимагають торкатися одного й того ж вводу двічі. Тоді це стає кошмаром. ☹
манатура

Знайшли Gema через одну з ваших інших публікацій ... класна мова. Наскільки неясним ви б сказали, що це Гема?
Йона

@Jonah, я б сказав, що її єдиною незрозумілою частиною є домен. Хоча це частково і тому, що функція недодокументована. Інакше мова - це сукупність чудових, але болісно обмежених можливостей. (Наприклад, розпізнавачі скелі, але вони були б набагато потужнішими, якби їх можна поєднати, як класи
класичних

наскільки популярною була гема в 90-х? і чи є у нього сучасні аналоги / конкуренти? ти використовуєш його для роботи чи просто знайшов для розваги?
Йона


2

Japt, 18 байт

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

Перевірте це


Чи можете ви додати пояснення?
Джим

@Jim, це просто порт мого рішення JS (Japt transpiles to JS), який повинен бути досить зрозумілим. Якщо ні, дивіться пояснення у розчині сітківки Okx; обидва мої роблять точно те саме.
Shaggy

4
??? @Downvoter: надішліть відгук.
Shaggy

@Shaggy ви сказали це самі, це в основному копіює пасту рішення Okx, і тоді ви зробили її на крок далі до мови, яка компілюється в точно такий же код, як і інша відповідь. Тож я прихильнився, тому що це було не унікальне рішення, яке не використовує жодних цікавих методів гольфу чи винахідливості; скоріше переклад іншої відповіді
Downgoat

1
@Downgoat, дякую за коментар. Однак я не сказав, що я скопіював рішення Okx, я просто направив Джима туди для пояснення. Якщо ви перевірите часові позначки, ви побачите, що я розмістив рішення JS майже в той самий час, що і Okx (можливо, я навіть був першим, але не можу побачити точні часові позначки на мобільному). Тоді я переніс власне рішення на іншу мову, що тут постійно відбувається так, якщо ви не скасуєте всі порти, я не розумію, чому ви виділили цей варіант.
Shaggy

2

Сід, 29 байт

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

Виконати з -r.

Використовує групи захоплення та замінює їх у протилежному порядку.


Можна скоротити [A-Za-z]до [^0-9]. Однак ви повинні вважати прапор частиною свого коду.
Денніс

Скільки рахується прапор?
Це Гай

Різниця між sed <command>і sed -r <command>, таким чином, три байти.
Денніс

@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/gi48 байт. Інакше, майже те саме.
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 Додав пояснення.
Ерік Аутгольфер

2

PHP, без регулярного вираження, 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&
Йорг Hü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 Done. Зазвичай я занадто лінивий, щоб додати його спочатку, особливо поки я все ще шукаю будь-яких удосконалень.
TheLethalCoder

1

Clojure, 104 88 байт

Про регулярному виразі дуже зручно ... в будь-якому випадку ( 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 і у нас була непарна кількість шматочків, то останній буде відкинутий.

Оригінал використовується багатослівний, але веселий, (juxt second first)а (set"0123456789")замість reverseі цілих діапазонів ASCII.

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

Чи можете ви додати посилання на TIO та пояснення?
Джим

1

QuadR , 15 байт

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

Спробуйте в Інтернеті!

Пояснення відверто вкрадено з Okx :

Це замінює регулярний вираз (\D+)(\d+)з \2\1. Давайте розбиємо це, якщо ви не знаєте, що це означає.

\DЗіставляють все , що не є числом "означає. \dозначає "співставити все, що є числом". В +знак означає "відповідати цьому принаймні один раз , але спробувати відповідати його стільки разів , скільки це можливо. Дужки визначають групу. Перша група є, (\D+)а друга -(\d+)

У другому рядку ми говоримо, що ми хочемо поставити все, що відповідало другій групі, а потім все, що було відповідне першій групі. Це ефективно підміняє літери та цифри.



1

Піп , 17 байт

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

Вводиться як аргумент командного рядка. Спробуйте в Інтернеті!

Пояснення

Тут використовується стандартна стратегія заміни регулярних виразів, дещо гольф.

Регекс є -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

мозковий ебать , 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

Вітаємо вас за те, що напевне відповідь не є найдовшою з відповідей!
Джим


0

Математика, 129 байт

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

Чи можете ви додати пояснення / неперевершений варіант?
Джим

нічого особливого для пояснення ... виявляє NumberString ділиться на 2 набори і riffles.Plus деякі умови "If", щоб працювати бездоганно
J42161217
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.