サブシーケンス置換


30

ほとんどの言語には、指定された部分文字列のすべての出現を文字列で検索し、それらを別の部分文字列に置き換える組み込み機能が付属しています。この概念を(必ずしも連続的ではない)サブシーケンスに一般化する言語は知りません。それがこの挑戦におけるあなたの仕事です。

入力は3つの文字列ABおよびCで構成されます。ここでBおよびCは同じ長さであることが保証されています。のBサブシーケンスとして表示される場合は、Aに置き換える必要がありCます。以下に簡単な例を示します。

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

次のように処理されます。

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

Bサブシーケンスとして検索する方法がいくつかある場合は、左端のものを貪欲に置き換える必要があります。

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

B複数のばらばらの場所で見つかった場合も同様です。

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

Bがに表示されない場合はAAそのまま出力する必要があります。

ルール

上述したように、3つの文字列を取りABそしてC入力などとの一番左の発生を置き換えるBにサブシーケンスとしてA持つCいかなるがある場合は、。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

3つの文字列は、回答で指定する必要がある一貫した順序で取得できます。あなたはそれを仮定し、同じ長さBC持つことができます。すべての文字列には英数字のみが含まれます。

標準の規則が適用されます。

テストケース

各テストケースは4行AB、:C、、その後に結果が続きます。

abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

abcdeedcba
ada
BOB
BbcOeedcbB

abcdeedcbaabcde
ed
12
abcd1e2cbaabcde

121
121
aBc
aBc

abcde
acb
123
abcde

ABC
ABCD
1234
ABC

012345678901234567890123456789
42
TT
0123T5678901T34567890123456789

edcbaedcbaedcbaedcba
abcde
12345
edcbaedcbaedcbaedcba

edcbaedcbaedcbaedcbaedcba
abcde
12345
edcb1edc2aed3bae4cba5dcba

daccdedca
ace
cra
dcrcdadca

aacbcbabcccaabcbabcaabbbbca
abaaaccbac
1223334444
aacbcbabcccaabcbabcaabbbbca

aacbcbabcccaabcbabcaabbbbcac
abaaaccbac
1223334444
1ac2cb2bccc33b3bab4aa4bbbc44

リーダーボード

この投稿の下部にあるスタックスニペットは、a)言語ごとの最短ソリューションのリストとして、b)全体的なリーダーボードとして、回答からリーダーボードを生成します。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

## Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

## Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

## Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、スニペットに表示することもできます。

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


単一の文字列のリストは、入力/出力に適していますか?
FryAmTheEggman

@FryAmTheEggmanフム、私は見つけることができる唯一のコンセンサスがある。この有効な文字列表現として単一文字列のリストに対処しません。メタ投稿をする価値があるかもしれません(特に、これはxnorの最新の課題でも出てきたと思うので)。私は今のところノーと言うつもりです。
マーティンエンダー

文字配列はどうですか?これは、言語に適切な文字列型がある場合でも許可されていることを意味するようです。
デニス

@Dennisええ、文字配列は問題ありませんが、シングルトン文字列は整数の配列をとして取るようなもの[[1], [2], [3]]です。
マーティンエンダー

OK、それを片付けてくれてありがとう。
デニス

回答:


3

ゼリー23 22 21バイト

='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?

オンラインでお試しください!最後の2つのテストケースではメモリが不足することに注意してください。

検証

$ head -n 5 test-cases
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

$ cat subseq-short
while read s; do
        read p; read r; read o; echo $o; read
        timeout 1s jelly eun $1 "='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?" "'$s'" "'$p'" "'$r'"
        (($?)) && echo '(killed)'
done < test-cases
$ ./subseq-short
abcdef12ijklmn3pqr45uvwxyz
abcdef12ijklmn3pqr45uvwxyz
BbcOeedcbB
BbcOeedcbB
abcd1e2cbaabcde
abcd1e2cbaabcde
aBc
aBc
abcde
abcde
ABC
ABC
0123T5678901T34567890123456789
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcba
edcb1edc2aed3bae4cba5dcba
edcb1edc2aed3bae4cba5dcba
dcrcdadca
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
(killed)
1ac2cb2bccc33b3bab4aa4bbbc44
(killed)

使い方

='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?  Main link. Arguments: string s, pattern p, replacement r

='                     Compare each character of s with each character of p.
                       This yields a 2D list. Each row corresponds to a char in p.
  T€                   Compute the truthy indices of each row, i.e., the indices
                       of all occurrences of that char in s.
   Œp                  Compute the Cartesian product of the lists of indices.
        $              Combine the two links to the left into a monadic chain:
      Ṣ€                 Sort each list of indices.
     f                   Filter, removing all non-sorted lists of indices.
         Ḣ             Head; take the first (sorted) list of indices.
          Ṭ            Truth; generate a list with 1's at those indices.
           œp³         Partition; split s at all 1's, removing those characters.
                  Ḋ?   If the partition has more than more than one element:
              ż⁵$        Zip the partition with r.
                 ³       Else, return s.

12

Python 2、88バイト

def f(a,b,c,o=""):
 for q in a:x=q==b[:1];o+=c[:x]or q;b=b[x:];c=c[x:]
 print[o,a][c>'']

3つの文字列を取り込んで、結果をSTDOUTに出力する関数。この関数は、単に文字列を1回渡すだけで、適切なcharを取得b,cして、更新します。

(交換後に試験するprintreturn)。

S = """
<test cases here>
"""

for T in S.split("\n\n"):
    A,B,C,D = T.split()
    assert f(A,B,C) == D

9

Java 7、141

これでもっとできることがあると思いますが、今は走らなければなりません。AとBにインデックスを保持するだけの単純な反復/置換です。

char[]h(char[]a,char[]b,char[]c){char[]d=a.clone();int i=0,j=0,k=b.length;for(;i<a.length&j<k;i++)if(a[i]==b[j])d[i]=c[j++];return j==k?d:a;}

あなたの喜びのためにホワイトスペース:

char[]h(char[]a,char[]b,char[]c){
    char[]d=a.clone();
    int i=0,j=0,k=b.length;
    for(;i<a.length&j<k;i++)
        if(a[i]==b[j])d[i]=c[j++];
    return j==k?d:a;
}

Whitespacedええ、それは完全に読みやすいです

じゃないですか?複数行のインデントバージョンを追加する主な理由は、水平スクロールを回避するためです。インライン空白はそれほど大きなIMOではありません;)
Geobits

[機能リクエスト]さらに多くの空白
アレックスA.


最後のバイト保存@Geobitsあなたがしなければj<k?a:d
Xanderhall

7

Lua、121バイト

簡単な解決策gsubにより、各文字で正確に1回反復し、文字列の新しいインスタンスで置き換えることができます。

3つのコマンドライン引数を介して入力を受け取り、文字列をSTDOUTに出力します。

a,b,c=...d=a:gsub(".",function(s)if b:find(s)then b=b:sub(2)x=c:sub(1,1)c=c:sub(2)return x end end)print(b~=''and a or d)

非ゴルフ

a,b,c=...               -- unpack the arguments into a, b and c
d=a:gsub(".",function(s)-- iterate over each character of the first argument
  if b:find(s)then      -- if the current character is in the set b
    b=b:sub(2)          -- remove it from b
    x=c:sub(1,1)        -- save the replacement character in x
    c=c:sub(2)          -- remove it from c
    return x            -- replace the current character with x
  end
end)
print(b~=''             -- if b is empty, we replaced all the character
      and a or d)       -- so output the result of gsub, else, output the first argument

6

Python 3、127バイト。

Katenkyoのおかげで16バイト節約されました。

まだこれに少し取り組んでいますが、私は思っていたよりも男はこの卑劣でした。

f=lambda a,b,c:a.replace(b[0],c[0],1)[:a.index(b[0])+1]+f(a[a.index(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else a

説明:そうですね、再帰。

テストケース:

assert f('abcdeedcba', 'ada', 'BOB') == 'BbcOeedcbB'
assert f('abcdeedcbaabcde', 'ed', '12') == 'abcd1e2cbaabcde'
assert f('012345678901234567890123456789', '42', 'TT') == '0123T5678901T34567890123456789'
assert f('ABC', 'ABCD', '1234') == 'ABC'

ゴルフ50オフの場合は+1ですが、続けてください!これは少なくとも私のJavaの答えを打ち負かす必要があります;)
Geobits

7
@Geobitsええ、Javaに負けたことはありません。これは私の最大の恥です。
モーガンスラップ

私は実際にはPythonに精通していませんがall(x in a for x in b)、bとaの要素が同じ順序で表示されるかどうか、またはそれらがここにある場合にのみチェックしますか?
かてんきょう

@Katenkyoすべてがそこにあるということだけですが、順序は、再帰時にスライスによって処理されます。
モーガンスラップ

また、return a.replace(b[0],c[0],1)[:l(b[0])+1]+f(a[l(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else aいくつかのバイトを節約しませんか?
かてんきょう

5

Python 3.5、87バイト

import re
lambda s,p,r:re.sub('(.*?)'.join(p),'\g<%d>'.join(r)%(*range(1,len(r)),),s,1)

repl.itを使用して、すべてのテストケースを検証します

使い方

  • '(.*?)'.join(p) 置換されるサブシーケンスとその要素間のすべてに一致する検索パターンを構築します。

    量指定子は遅延しているため、それぞれ(.*?)はできるだけ少ない文字に一致します。

    パターンのghost場合、構築された正規表現はg(.*?)h(.*?)o(.*?)s(.*?)tです。

  • '\g<%d>'.join(r)%(*range(1,len(r)),) 文字列フォーマットを使用して、置換文字列を構築します。

    それぞれ\g<n>が、n 番目にキャプチャされたグループを参照し\nます。

    置換の12345場合、構築される文字列は1\g<1>2\g<2>3\g<3>4\g<4>5です。

  • re.sub(...,...,s,1)文字列で最大1つの置換を実行しますs


4

Pyth、27

.xuXG.*HC,hSI#.nM*FxRcQ1zwQ

テストスイート

テストスイートでは、最後の2つのケースがメモリ不足になるため省略します。ここで使用されるアルゴリズムは、最初の文字列の2番目の文字列の各文字のすべてのインデックスを検索し、それらのインデックスのすべての可能な順序を検索し、ソートされた順序のみを取得します。次に、これらの最初の1つをソートされた順序で最初の文字列のインデックスのリストとして使用して、3番目の文字列の値で更新します。

もっと短いものがあるはずだと思う.nM*F...


4

MATL、33バイト

y!=[]0b"@n:!<@*fX<h5Mt?}.]]?iw(}x

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

説明

y!      % Implicitly input first two strings. Duplicate the first and transpose
=       % Compare the two strings element-wise. Gives a 2D array with all combinations
[]      % Push empty array. Indices of matching elements will be appended to this
0       % Push a 0. This is the index of last character used up in first string
b       % Bubble up (rearrange elements in stack) to move 2D array to top
"       % For each column of that array (each char of the second string)
  @     %   Push current column
  n:!   %   Transform into column array of consecutive values starting from 1
  <     %   Compare with index of last character used up of first string
  @*    %   Push current column again. Multiply element-wise (logical AND)
  fX<   %   Find index of first matching character, or empty if there's none
  h     %   Append to array containing indices of matching elements
  5Mt   %   Push index of matching character again. Duplicate
  ?}    %   If it's empty
    .   %     Break loop
  ]     %   End if
]       % End for
        % The top of the stack now contains a copy of the index of last matching
        % character, or an empty array if there was no match
?       % If non-empty: all characters were matched
  i     %   Input third string
  w     %   Swap top two elements in stack
  (     %   Assign the characters of the third string to first string at found indices
}       % Else: the original string needs to be output
  x     %   Delete (partial) array of matching indices. Leave original string in stack
        % End if
        % Implicitly display (either modified string or original string)

3

JavaScript(ES6)、84バイト

(a,b,c)=>[...b].every((q,i)=>r[p=a.indexOf(q,p)]=~p++&&c[i],p=0,r=[...a])?r.join``:a

説明/テスト


3

JavaScript(ES6)、84 76バイト

(a,b,c)=>a.replace(RegExp([...b].join`(.*?)`),c.replace(/\B/g,(_,i)=>'$'+i))

これはRegExpの仕事だと確信していたからです。

編集:@MartinBüttner♦のおかげで8バイト保存されました。

@KevinLauのRuby回答の移植には82バイトかかりました。

([...a],[...b],[...c])=>(d=a.map(e=>e==b[0]?c.shift(b.shift()):e),b[0]?a:d).join``

再帰的なRegExpソリューションも試しましたが、90バイトかかりました。

f=(a,[b,...d],[c,...e])=>b?a.replace(RegExp(b+'(.*'+d.join`.*`+'.*)'),(_,s)=>c+f(s,d,e)):a

3

ジュリア、89 70バイト

f(s,a,b,i=0)=(o=join(["$a "[i+1]!=c?c:b[i+=1]for c=s]);i<endof(a)?s:o)

インデックスiを使用して、パターン/置換文字列を繰り返し処理します。@Dennisのおかげで-19バイト!


2

C、98バイト

char*f(i,o,s,r)char*i,*o,*s,*r;{char*I=i,*O=o;for(;*i;++i,++o)*o=*i==*s?++s,*r++:*i;return*s?I:O;}

/ *拡張コード* /

char *f(i, o, s, r)
    char *i, *o, *s, *r;
{
    char *I=i, *O=o;
    for (;  *i;  ++i,++o)
        *o = (*i==*s) ? (++s,*r++) : *i;
    return *s ? I : O;
}

引数は次のとおりです。私は、文字列NPUT、O utputバッファ、 earchが文字列は、 Rの eplacement。

入力と出力の開始を記憶した後、入力を調べて、ヒットしたときに置換を置き換えて進めます。最後に、置換が不足している場合は、出力バッファを返します。それ以外の場合は、変更されていない入力を返します。

/ *テスト* /

struct T
{
    const char *input;
    const char *search;
    const char *replace;
    const char *expected;
};

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int i;
    static const struct T test[] = {
        { "abcdefghijklmnopqrstuvwxyz",
          "ghost",
          "12345",
          "abcdef12ijklmn3pqr45uvwxyz"},
        { "abcdeedcba",
          "ada",
          "BOB",
          "BbcOeedcbB"},
        { "abcdeedcbaabcde",
          "ed",
          "12",
          "abcd1e2cbaabcde"},
        { "121",
          "121",
          "aBc",
          "aBc"},
        { "abcde",
          "acb",
          "123",
          "abcde"},
        { "ABC",
          "ABCD",
          "1234",
          "ABC"},
        { "012345678901234567890123456789",
          "42",
          "TT",
          "0123T5678901T34567890123456789"},
        { "edcbaedcbaedcbaedcba",
          "abcde",
          "12345",
          "edcbaedcbaedcbaedcba"},
        { "edcbaedcbaedcbaedcbaedcba",
          "abcde",
          "12345",
          "edcb1edc2aed3bae4cba5dcba"},
        { "daccdedca",
          "ace",
          "cra",
          "dcrcdadca"},
        { "aacbcbabcccaabcbabcaabbbbca",
          "abaaaccbac",
          "1223334444",
          "aacbcbabcccaabcbabcaabbbbca"},
        { "aacbcbabcccaabcbabcaabbbbcac",
          "abaaaccbac",
          "1223334444",
          "1ac2cb2bccc33b3bab4aa4bbbc44"
        }
    };

    for (i = 0;  i < (sizeof test) / (sizeof test[0]);  ++i) {
        const struct T *t = test+i;
        char *out = malloc(strlen(t->input)+1);
        char *result = f(t->input, out, t->search, t->replace);
        if (strcmp(t->expected, result))
            printf("Failed test %d; result = \"%s\"\n", i, result);
    }
    return EXIT_SUCCESS;
}

2

R、76バイト

function(a,b,c){s=substr;for(x in 1:nchar(b)){a=sub(s(b,x,x),s(c,x,x),a)};a}

使用する sub最初の一致を置き換えるためにし

非ゴルフ

function(a,b,c){                    # function with 3 arguments as per description
  s=substr;                         # alias for substr (saves 1 byte)
   for(x in 1:nchar(b)){            # index 1 to number character in b
     a=sub(s(b,x,x),s(c,x,x),a)};   # replace first instance of b[x] in a  
                                    # with c[x] and reassign to a
 a}                                 # return a

2

C ++、204バイト

ゴルフ

#include<iostream>
#include<string>
int main(){std::string a, b, c;std::cin>>a>>b>>c;int t=0;for(int x=0;x<b.length();x++){t=a.find(b[x],t);if(t!=-1){a.replace(t,1,c.substr(x,1));}}std::cout<<a;return 0;}

非ゴルフ

#include<iostream>
#include<string>

int main()
{
    std::string a, b, c;
    std::cin>>a>>b>>c;
    int t = 0;
    for (int x=0;x<b.length();x++) {
        t = a.find(b[x], t);
        if (t != -1) {
            a.replace(t,1,c.substr(x, 1));
        }
    }
    std::cout<<a;
    return 0;
}

あなたが使用stdを保証するほど十分に使用しているとは思いませんusing namespace std;。、、およびを使用するstd::cinstd::coutstd::string5バイト節約されます。これは、これらがその名前空間の唯一の用途であると思われるためです。
バリューインク

@KevinLauありがとう!あなたは非常に正しいです、私はそれを考えましたが、実際にそれが文字を節約することを実現するためにカウントしませんでした。
ミシェルフランシスブスティロス

ああ!もう1つ重要です。もう一度あなたのコードの上に読んだ後、私はあなたが貪欲内の各文字の一番左の発生を交換する実現ba、それ以降の文字は、同様に、以前の文字の後でなければなりません。(テストケース3を見て、出力と比較してabc21ed...、期待される出力がabcd1e2...!のときにコードが出力されることがわかると思います。)
値インク

のでideone C ++コンパイラ14入力"Adregffftd \ NA23 \ nzac \ n"は10分前のコードの上に、 "zdregffftd"の出力を生成する代わりに、 "Adregffftd"
RosLuP


2

Haskell、87バイト

x@((a,b):c)#(d:e)|a==d,([],z)<-c#e=([],b:z)|0<1=(d:)<$>x#e
x#y=(x,y)
a!b=snd.(zip a b#)

Haskellの回答がないことに気づき、修正することにしました。これは、!引数の順序pattern-replacement-stringを持つ三項関数を定義します。 ここで試してみてください。

説明

補助関数#は、x文字のペア(パターンと置換)と文字列のリストを受け取りますy。の「パターン」文字がxのサブシーケンスを形成する場合、y空のリストを返し、y各パターン文字が対応するものに置き換えられます。それ以外の場合は、ペアを返します(x,y)。この関数!は、パターンと置換文字列をxに圧縮し、適用#しますx、3番目の文字列に、結果の2番目のコンポーネントを返します。

x@((a,b):c)#(d:e)  -- First case of #: both arguments nonempty.
  |a==d,           -- If the pattern char matches the string's head,
   ([],z)<-c#e     -- and the pattern's tail is a subsequence of the string's tail,
  =([],b:z)        -- tack the replacement char to the recursion result.
  |0<1             -- Otherwise,
  =(d:)<$>x#e      -- recurse with the same pairs and tack string's head to result.
x#y=(x,y)          -- If either argument is empty, just pair them.

パターンが文字列のサブシーケンスである場合、コードはO(n)時間で実行され、文字列を1回再帰的に通過し、プロセスで置換を貪欲に構築します。ただし、パターンがサブシーケンスでない場合、最悪の場合はO(2 n時間で実行されます。これは、パターンと文字列に一致する文字があるすべての位置で、関数がパターンを実際にサブシーケンスであるかどうかを確認するために自分自身を呼び出し、そうでないことを確認し、実際に結果を計算するためにもう一度呼び出すためです。


2

JavaScript(ES6)、100 95バイト

(a,b,c)=>1?(t=[...a].map(e=>b[0]==e?(u=c[0],b=b.slice(1),c=c.slice(1),u):e).join``,b==""?t:a):a

これは有効なJavaScript Lambda関数です。functionとして出力しますreturn。3つの引数(a,b,c)を取ります。f=最初に追加して、のように呼び出しf(arg1,arg2,arg3)ます。

f=(a,b,c)=>1?(t=[...a].map(e=>b[0]==e?(u=c[0],b=b.slice(1),c=c.slice(1),u):e).join``,b==""?t:a):a

console.log(f(prompt("Value for A"),prompt("Value for B"),prompt("Value for C")))


PPCGへようこそ!名前のない関数は一般に許容されるためf=、関数が再帰的でない限り、関数は必要ありませんが、見た目は異なります。
マーティンエンダー

@MartinBüttnerありがとう!:)私の答えを更新しました。
アルジュン

残念ながら、aパターンが含まれていない場合、これは失敗します。文字列の配列を返すことが許容されるかどうかもわかりません。
デニス

@Dennisソリューションを更新しました。今は正しいと思う。このような返信と更新が遅くなってすみません。(あなたのコメントに気付いたので、遅れました)
Arjun

@MartinEnder私はすべての解決策を試していましたが、これが間違っていることがわかりました。しかし、私は今それを修正しました。そして、それは5バイト短くなっています(多くのゴルフ可能な場所を手つかずのままにしていたためです;私はそのとき初心者のゴルファーでした。間違ったソリューションを投稿してすみません。
アルジュン


1

オクターブ、97バイト

function A=U(A,B,C)t=0;for s=B if p=find(A(t+1:end)==s,1) D(t=p+t)=~0;else return;end;end;A(D)=C;

置換するサブシーケンスを反復処理します。最初の文字の最初の出現を見つけ、残りの文字列で次の文字を見つけ、繰り返します。これの興味深い点は次のとおりです。

D(t=p+t)=~0

D(     )      %// D is a logical mask of characters to replace in the input string
  t=p+t       %// t is the current end of D 
              %// p is the location of the character to replace
              %// update t and use as index to grow D
        =~0   %// make it so, number 1

ideoneは ''以外の名前の関数をまだ受け付けていないため、ここでサンプルを実行します。簡潔にするため、入力は最初のいくつかのテストケースについてのみ表示されます。keyは予想される出力、ans関数の出力です。

A = abcdefghijklmnopqrstuvwxyz
B = ghost
C = 12345
key = abcdef12ijklmn3pqr45uvwxyz
ans = abcdef12ijklmn3pqr45uvwxyz
A = abcdeedcba
B = ada
C = BOB
key = BbcOeedcbB
ans = BbcOeedcbB
A = abcdeedcbaabcde
B = ed
C = 12
key = abcd1e2cbaabcde
ans = abcd1e2cbaabcde
key = aBc
ans = aBc
key = abcde
ans = abcde
key = ABC
ans = ABC
key = 0123T5678901T34567890123456789
ans = 0123T5678901T34567890123456789
key = edcbaedcbaedcbaedcba
ans = edcbaedcbaedcbaedcba
key = edcb1edc2aed3bae4cba5dcba
ans = edcb1edc2aed3bae4cba5dcba
key = dcrcdadca
ans = dcrcdadca
key = aacbcbabcccaabcbabcaabbbbca
ans = aacbcbabcccaabcbabcaabbbbca
key = 1ac2cb2bccc33b3bab4aa4bbbc44
ans = 1ac2cb2bccc33b3bab4aa4bbbc44

予想外の場所でのオクターブの割り当て(D(t=...))が私を困惑させ続けます:-)
ルイスメンドー

1
@LuisMendoハハ...それはほとんど...スタックのようなものです!:)
ビーカー

1

Python 3、123バイト

私が共有したかった別のアプローチは、数バイト短くなっています。標準ライブラリ/正規表現に対するルールはありませんか?

import re
j=''.join
m='(.*?)'
def f(A,B,C):
 *r,l=(re.findall(m+m.join(B)+'(.*)',A)or[[A]])[0]
 print(j(map(j,zip(r,C)))+l)

PS。これは私の最初のゴルフです。問題/改善点をお知らせください。


1

Pyth、22バイト

|eJ:Ej"(.*?)"+E\$3s.iJ

Pyth Compilerですべてのテストケースを検証する

バックグラウンド

を追加し$て配置することにより、パターンから正規表現を構築します(.*?)すべての文字の間にます。この正規表現は、置換されるサブシーケンスとその要素間のすべて、および文字列の最後までのすべてと一致します。

量指定子は遅延しているため、それぞれ (.*?)はできるだけ少ない文字に一致します。

パターンゴーストの場合、構築された正規表現は g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$です。

パターンが入力と一致する場合、組み込み r<str><regex>3は、事前一致(サブシーケンスの前のすべて)、キャプチャされたすべてのグループ(サブシーケンスの中間および後のすべて)、および一致後(空の文字列)を含む配列を返します。

パターンが一致しない場合、ビルトインは元の入力を含むシングルトン配列を返します。

使い方

|eJ:Ej"(.*?)"+E\$3s.iJQ  (implicit) Store the first line of input in Q.

             +E\$        Read the third line of input (pattern) and append '$'.
     j"(.*?)"            Join the result, separating by "(.*?)".
    E                    Read the third line of input (string).
   :             3       Match the string against the regex, as detailed above.
  J                      Save the returned array in J.
 e                       Extract the last element of J. This is an empty string
                         for a successful match or the original string.
|                        Logical OR; replace an empty string with the following:
                   .iJQ    Interleave J and the replacement.
                  s        Flatten the resulting array of strings.

1

ゼリー、23 バイト

Ṭœpż⁵
0ẋai1
⁴='-;ç\ñ⁴P?

これは、他のJelly answerよりも2バイト長くなりますがすぐに終了します。オンラインでお試しください!

検証

$ head -n 5 test-cases
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

$ cat subseq-fast
while read s; do
        read p; read r; read o; echo $o; read
        timeout 10s jelly eun $1 "Ṭœpż⁵¶0ẋai1¶⁴='-;ç\ñ⁴P?" "'$p'" "'$s'" "'$r'"
        (($?)) && echo '(killed)'
done < test-cases
$ ./subseq-fast
abcdef12ijklmn3pqr45uvwxyz
abcdef12ijklmn3pqr45uvwxyz
BbcOeedcbB
BbcOeedcbB
abcd1e2cbaabcde
abcd1e2cbaabcde
aBc
aBc
abcde
abcde
ABC
ABC
0123T5678901T34567890123456789
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcba
edcb1edc2aed3bae4cba5dcba
edcb1edc2aed3bae4cba5dcba
dcrcdadca
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
aacbcbabcccaabcbabcaabbbbca
1ac2cb2bccc33b3bab4aa4bbbc44
1ac2cb2bccc33b3bab4aa4bbbc44

使い方

⁴='-;ç\ñ⁴P?  Main link. Arguments: pattern p, string s, replacement r

⁴='          Compare each character of s with each character of p.
             This yields a 2D list. Each row corresponds to a char in p.
   -;        Prepend -1 to the 2D list, yielding a ragged array.
     ç\      Cumulatively reduce the array by the second helper link.
         P?  If the product of the resulting list is non-zero:
       ñ       Call the first helper link with the list and s as arguments.
        ⁴      Else, return s.


Ṭœpż⁵        First helper link. Arguments: L (list of indices), r (replacement)

Ṭ            Truth; generate a list with 1's at those indices.
 œp          Partition; split s at all 1's, removing those characters.
   ż⁵        Zip the partition with r.


0ẋai1        Second helper link. Arguments: n (integer), B (list of Booleans)

0ẋ           Generate a list of n zeroes.
  a          Perform logical AND with B.
             This zeroes out the with n elements of B.
   i1        Compute the first index of 1.


1

Java 7、102バイト

void L(char[]s,char[]l,char[]r){for(int x=0,y=0;x<s.length&&y<l.length;x++)if(s[x]==l[y])s[x]=r[y++];}

詳細な 試用はこちら

// String, Lookup, Replacement
void L(char[]s, char[]l, char[]r)
{
    for(int x=0, y=0; x < s.length && y < l.length; x++)
        if(s[x] == l[y])
            s[x] = r[y++];
}

1

ジュリア、93 90 86バイト

f(s,p,r)=(try s=join([match(Regex(join("^$p\$","(.*?)")),s).captures';[r...""]])end;s)

マッチが成功したかどうかを個別にテストする必要があると、スコアが破壊されます。置換にはにキャストする必要がありますがBase.SubstitutionString、おそらくそれだけの価値はありません...

試運転

julia> f(s,p,r)=(try s=join([match(Regex(join("^$p\$","(.*?)")),s).captures';[r...""]])end;s)
f (generic function with 1 method)

julia> f("aacbcbabcccaabcbabcaabbbbca","abaaaccbac","1223334444")
"aacbcbabcccaabcbabcaabbbbca"

julia> f("aacbcbabcccaabcbabcaabbbbcac","abaaaccbac","1223334444")
"1ac2cb2bccc33b3bab4aa4bbbc44"

1

ジュリア、62 59 58バイト

f(s,p,r)=(try s[[i=findnext(s,c,i+1)for c=p]'],i=r,0end;s)

I / Oは文字配列の形式です。

検証

julia> f(s,p,r)=(try s[[i=findnext(s,c,i+1)for c=p]'],i=r,0end;s)
f (generic function with 2 methods)

julia> F(s,p,r)=join(f([s...],[p...],[r...])) # string/char array conversion
F (generic function with 1 method)

julia> F("aacbcbabcccaabcbabcaabbbbca","abaaaccbac","1223334444")
"aacbcbabcccaabcbabcaabbbbca"

julia> F("aacbcbabcccaabcbabcaabbbbcac","abaaaccbac","1223334444")
"1ac2cb2bccc33b3bab4aa4bbbc44"

1

PHP、130 109バイト

まだ短くしたいです。3バイト(救うことができる""<場合)をB含んでいないことが保証されました0

for($s=($a=$argv)[1];""<$c=$a[2][$i++];)if($p=strpos(_.$s,$c,$p+1))$s[$p-1]=$a[3][$k++];echo$k<$i-1?$a[1]:$s;

コマンドラインから引数を取ります。で実行-rます。

見つかった文字を置き換えます。
すべての文字が置き換えられた場合にコピーを印刷します。オリジナルのほか。


1

ルビー、70 64 59 58バイト

匿名関数。文字列aをウォークスルーして、次の文字に従って文字が置き換えられた新しい文字列を作成しbcbし、最後にすべての文字が使い果たされた場合、新しく構築された文字列を返し、そうでない場合は元の文字列を返します。

@histocratは、 gsub

@Cyoceのおかげで1バイト節約されました。

->a,b,c{i=0;s=a.gsub(/./){$&==b[i]?c[~-i+=1]:$&};b[i]?a:s}

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


あなたは置き換えることにより、バイトを保存することができ-1+i+=1~-i+=1
Cyoce

0

Perl、80 + 1 = 81バイト

-pフラグで実行

$a=join"(.*?)",split//,<>;$b.=$_." .\$".++$;."."for split//,<>;chop$b;s/$a/$b/ee

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

コードは手続き的に検索と置換の正規表現コマンドを生成し、コードの最後のビットで実行します。

ghost最初の例の文字列はstring に変換されますg(.*?)h(.*?)o(.*?)s(.*?)t(.*?)。これは、g0個以上の文字が続き、hその後に0個以上の文字が続き、etcが続くことを意味します。*?ことを意味します。 「可能な限り一致するデフォルトの代わりに、可能な限り少ない文字数。

文字列12345はに変換1 .$1.2 .$2.3 .$3.4 .$4.5 .$5され、正規表現の実行後に評価されます。それぞれ$1,$2,$3,$4,$5は、実際には、最初の文字列からのキャプチャグループ(括弧内)への後方参照です。


このコードを数バイト節約することを提案します:perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'。自分でそれを見つけましたが、それはあなたのものに非常に近いので、私はそれを投稿しません、それは2つの非常に近い答えになるでしょうが、あなたのものを自由に編集してください!
ダダ

私はそれを最近の問題に「関連する」質問としてリストしたのを見たので、ちょうどこれを試してみました。私が得た最高のものperl -E 'chomp(($f,$t,$s)=(<>));$f=join"(.*?)",split"",$f;@r=split"",$t;@t=shift@r;push@t,"\${",++$x,"}"for(@r);$t=join"",@t;say$s=~s/$f/$t/r;'
ウィルクロフォード

0

Clojure、113バイト

#(apply str((reduce(fn[[b c r]a](if(=(first b)a)[(rest b)(rest c)(conj r(first c))][b c(conj r a)]))[%2%3[]]%)2))

基本的なreduce、これらすべての長いfirstrestおよびconj関数呼び出しについてあまり幸せではありません。より良いアプローチを期待しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.