文字と数字の実行を交換する


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+)2つ目は(\d+)

2行目では、2番目のグループと一致したものをすべて配置し、その後に最初のグループと一致したものを配置したいと言います。これにより、文字と数字の実行が効果的に交換されます。

オンラインでお試しください!


7

Haskell58 56バイト

2バイトを削る@Laikoniに感謝

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

で2バイトを保存します(a,(b,y))<-span(<':')<$>span(>'9')s
ライコニ

1
でさらに節約(a,(b,y):_)<-lex<$>span(>'9')sオンラインでお試しください!
ライコニ

@ライコニ:ヒントをありがとう!どのようにlex機能するのかは明確ではないので、今のところそれを含めることは控えます。いずれにせよ、プレリュード
ジュリアン・ウルフ

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

オンラインでテストしてください!

注:これは不安定なアルファ版であるため、このリンクが破損した場合は、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

でそれを行う方法があるかどうかを把握しようとしていたò
シャギー

5

CJam32 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

Gema、11文字

<L><D>=$2$1

サンプル実行:

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

だから...短い。つまり、それはゴルフの言語ではなく、たったの11ですか?ワオ。
エリックアウトゴルファー

ええ、ただし同じ入力を2回タッチする必要のないタスクの場合のみです。それは悪夢になります。☹
manatwork

他の投稿のいずれかでGemaを見つけました...クールな言語。Gemaはどれほど曖昧だと思いますか?
ジョナ

@Jonah、その唯一の不明瞭な部分はドメインだと思います。これは、機能が文書化されていないため、部分的にはありますが。それ以外の場合、この言語は優れた機能ですが、非常に限られた機能のコレクションです。(たとえば、
レコグナイザーは揺れ

90年代のジェマの人気度は?そして、それは現代のカウンターパート/競合他社を持っていますか?仕事に使っていますか、それとも楽しみのために見つけましたか?
ジョナ


2

Japt、18バイト

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

試して


説明を追加できますか?
ジム

@Jim、これは私のJSソリューション(JaptからJSへのトランスパイル)の単なる移植版であり、一目瞭然です。そうでない場合は、OxxのRetinaソリューションの説明を参照してください。私の両方がまったく同じことをします。
シャギー

4
??? @Downvoter:フィードバックを提供してください。
シャギー

@Shaggyはあなたがそれを自分で言った、それは基本的にOkxのソリューションのコピーペーストであり、それからあなたは他の答えとまったく同じコードにコンパイルする言語にさらに一歩踏み込んだ。だから、これはユニークな解決策ではなく、興味深いゴルフ技術や工夫を使っていないので、私はダウン票を投じました。むしろ別の答えの翻訳
Downgoat

1
@Downgoat、コメントありがとう。しかし、私はOkxのソリューションをコピーしたとは言わず、単に説明のためにそこにジムを向けました。タイムスタンプを確認すると、Oxとほぼ同時にJSソリューションを投稿していることがわかります(最初だったかもしれませんが、モバイルでは正確なタイムスタンプが表示されません)。その後、私は自分のソリューションを別の言語に移植しましたが、これはここで常に発生します。したがって、すべてのポートを降格しない限り、なぜこの1つを選んだのかわかりません。
シャギー

2

Sed、29バイト

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

-rで実行します。

キャプチャグループを使用し、それらを逆の順序で置き換えます。


あなたは短縮することができます[A-Za-z][^0-9]。ただし、フラグをコードの一部としてカウントする必要があります。
デニス

旗はいくらですか?
それはガイ

sed <command>sed -r <command>そう3バイト、。
デニス

@Dennis、それは違います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/gi、48バイトでした。それ以外はほぼ同じです。
トビー・スペイト

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&
ヨルクヒュルサーマン


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にリンクを追加できますか?
ジム

@ジム完了。私は通常、最初に追加するのが面倒なので、特に改善を探している間は特にそうです。
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奇数のチャンクがある場合、最後のチャンクは破棄されます。

オリジナルはASCII整数範囲の代わりに冗長で楽しいもの(juxt second first)を使用しました。(set"0123456789")reverse

#(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+)2つ目は(\d+)

2行目では、2番目のグループと一致したものをすべて配置し、その後に最初のグループと一致したものを配置したいと言います。これにより、文字と数字の実行が効果的に交換されます。



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}、2番目のグループ(c)と最初のグループ(b)を連結するコールバック関数です。(関数の最初の引数にaは、完全な一致が含まれます。)

これは、naiveより3バイト短いですaR`(\D+)(\d+)``\2\1`


1

brainfuck、98バイト

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

オンラインでお試しください!

説明

このプログラムは、まだ出力されていない文字のキューを保持し、適切なときに出力します。

このプログラムの鍵は>>----[---->+<<<-[>]>]です。入力セルの右側の3つのセルはゼロから始まります。入力が1から63までのコードポイントである場合、これはポインターを1スペース右に移動し、入力をこの新しい位置の2スペース右に配置します。それ以外の場合、ポインターは2スペース右に移動し、新しい位置の1スペース右のセルが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

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

説明を追加できますか?
ジム

説明することはあまりありません... NumberStringが2セットに分割され、完全に機能するためにいくつかの「If」条件が検出されることを検出します
-J42161217
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.