Поменять местами буквы и цифры

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

Во второй строке мы говорим, что хотим поместить то, что было сопоставлено второй группой, а затем то, что было сопоставлено первой группой. Это эффективно меняет буквы и цифры.

Попробуйте онлайн!

Okx
источник
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.
Лайкони
1
Сэкономьте еще больше (a,(b,y):_)<-lex<$>span(>'9')s: попробуйте онлайн!
Лайкони
@Laikoni: Спасибо за совет! Я не совсем понимаю, как это lexработает, поэтому я пока воздержусь от включения этого. В любом случае, приятно знать, что в Prelude есть что-то подобное
Джулиан Вольф
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

Pyth , 15 байт

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

объяснение

     :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

Тестовый пакет .

Дрянная Монахиня
источник
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
ETHproductions
источник
Пытался выяснить, есть ли способ сделать это с ò.
Лохматый
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
manatwork
источник
Так коротка. Я имею в виду, это не язык игры в гольф, а просто 11? Вау.
Эрик Outgolfer
Да, но только для задач, которые не требуют двойного нажатия на один и тот же ввод. Тогда это становится кошмаром. Man
manatwork
Нашел Gema через один из ваших других постов ... крутой язык. Насколько неясным вы бы назвали Джему?
Иона
@ Джона, я бы сказал, что единственная неясная часть - это домен. Хотя это отчасти потому, что эта функция недокументирована. В противном случае язык представляет собой набор замечательных, но болезненно ограниченных возможностей. (Например, распознаватели качаются, но они были бы намного мощнее, если бы их можно было комбинировать, как классы символов регулярных выражений.)
manatwork
насколько популярной была гема в 90-х? и есть ли у него современные аналоги / конкуренты? Вы используете это для работы или просто нашли это для удовольствия?
Иона
2

Japt, 18 байт

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

Проверь это

мохнатый
источник
Можете ли вы добавить объяснение?
Джим
@ Джим, это просто порт моего решения JS (Japt переносится в JS), что должно быть довольно самоочевидно. Если нет, см. Объяснение в решении Retx для Okx; оба мои делают одно и то же.
Лохматый
4
??? @ Downvoter: пожалуйста, оставьте отзыв.
Лохматый
@ Shaggy, вы сказали это сами, это в основном копирование решения Okx, а затем вы сделали еще один шаг вперед к языку, который компилируется в тот же код, что и ваш другой ответ. Так что я понизил голос, потому что это не было уникальным решением, в котором не использовались какие-либо интересные техники игры в гольф или изобретательность; скорее перевод другого ответа
Downgoat
1
@ Downgoat, спасибо за комментарий. Однако я не сказал, что скопировал решение Оккса, я просто направил туда Джима для объяснения. Если вы проверите метки времени, вы увидите, что я разместил свое решение JS почти в то же время, что и Okx (возможно, я даже был первым, но я не вижу точные метки времени на мобильных устройствах). Затем я перенес свое собственное решение на другой язык, что происходит здесь постоянно, поэтому, если вы не отказываетесь от голосования по всем портам, я не понимаю, почему вы выбрали это.
Лохматый
2

Sed, 29 байт

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

Запустите с -r.

Использует группы захвата и заменяет их в обратном порядке.

Это парень
источник
Вы можете сократить [A-Za-z]до [^0-9]. Тем не менее, вы должны считать флаг как часть вашего кода.
Деннис
Сколько стоит флаг?
Это парень
Разница между sed <command>а sed -r <command>, так три байта.
Деннис
@ Денис, это разница между sed -f filenameи sed -rf filename(или между sed -e 'command'и sed -re 'command'): один байт.
Тоби Спейт
Я пропустил ключевую фразу (« начиная с буквы ») в вопросе, поэтому имел s/([a-z]+)([0-9]+)|([0-9]+)([a-z]+)/\2\1\4\3/gi48 байтов. В остальном, примерно так же.
Тоби Спейт
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
Эрик Outgolfer
источник
2
Можете ли вы добавить объяснение?
Джим
@Jim Добавлено объяснение.
Эрик Outgolfer
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
Titus
источник
Я имею в виду, вы можете использовать ~вместоa&
Jörg 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();
    }
}
TheLethalCoder
источник
Можете ли вы добавить ссылку на TIO ?
Джим
@ Джим Готово. Я обычно слишком ленив, чтобы добавить его вначале, особенно пока я все еще ищу какие-либо улучшения.
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"))%)))))
NikoNyrh
источник
Можете ли вы добавить ссылку на TIO и объяснение?
Джим
1

QuadR , 15 байт

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

Попробуйте онлайн!

Пояснения, явно украденные у Okx :

Это заменяет регулярное выражение (\D+)(\d+)с \2\1. Давайте разберемся с этим, если вы не знаете, что это значит.

\DСопоставляют все , что не является числом "означает. \dозначает «соответствовать всему, что является числом». В +знак означает "соответствовать этому по крайней мере один раз , но попытаться соответствовать его столько раз , сколько это возможно. Скобки определяют группу. Первая группа, (\D+)а вторая(\d+)

Во второй строке мы говорим, что хотим поместить то, что было сопоставлено второй группой, а затем то, что было сопоставлено первой группой. Это эффективно меняет буквы и цифры.

Адам
источник
1

PowerShell , 40 байт

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

Попробуйте онлайн!


PowerShell идеально подходит для этого, поскольку он поддерживает поиск и замену регулярных выражений «из коробки». Реквизиты идут в @Okx для решения регулярных выражений.

Джефф Фриман
источник
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`.

DLosc
источник
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
Nitrodon
источник
Поздравляю с ответом, который не самый длинный из них!
Джим
0

Mathematica, 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)&
J42161217
источник
Можете ли вы добавить версию объяснения / ungolfed?
Джим
объяснять особо нечего ... обнаруживает, что NumberString делится на 2 комплекта и риффлы. Плюс некоторые условия "если", чтобы работать идеально
J42161217