Substitusi Selanjutnya

30

Sebagian besar bahasa dilengkapi dengan built-in untuk mencari string untuk semua kemunculan substring yang diberikan dan menggantikannya dengan yang lain. Saya tidak tahu bahasa apa pun yang menggeneralisasikan konsep ini untuk (tidak harus berdampingan). Jadi itulah tugas Anda dalam tantangan ini.

Input akan terdiri dari tiga string A, Bdan C, di mana Bdan Cdijamin memiliki panjang yang sama. Jika Bmuncul sebagai urutan di Adalamnya harus diganti dengan C. Ini adalah contoh sederhana:

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

Ini akan diproses seperti ini:

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

Jika ada beberapa cara untuk menemukannya Bsebagai urutan, Anda harus dengan rakus mengganti yang paling kiri:

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

Hal yang sama berlaku jika Bdapat ditemukan di beberapa tempat terpisah:

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

Ketika Btidak muncul A, Anda harus output Atidak berubah.

Aturan

Seperti yang dinyatakan di atas, ambil tiga string A, Bdan Csebagai input dan ganti kejadian paling kiri Bsebagai berikutnya Adengan C, jika ada.

Anda dapat menulis sebuah program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi dan mengeluarkan hasilnya melalui STDOUT (atau alternatif terdekat), nilai pengembalian fungsi atau parameter function (out).

Anda dapat mengambil tiga string dalam urutan yang konsisten yang harus Anda tentukan dalam jawaban Anda. Anda mungkin menganggap itu Bdan Cmemiliki panjang yang sama. Semua string hanya akan berisi karakter alfanumerik.

Aturan standar berlaku.

Uji Kasus

Setiap kasus uji empat baris: A, B, Cdiikuti oleh hasilnya.

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

Papan peringkat

Cuplikan Stack di bagian bawah posting ini menghasilkan papan peringkat dari jawaban a) sebagai daftar solusi terpendek per bahasa dan b) sebagai papan peringkat keseluruhan.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

## Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

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

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

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

Anda juga dapat membuat nama bahasa menjadi tautan yang kemudian akan muncul di cuplikan:

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

Martin Ender
sumber
Apakah daftar string karakter tunggal boleh untuk input / output?
FryAmTheEggman
@FryAmTheEggman Hm, satu-satunya konsensus yang dapat saya temukan adalah ini yang tidak membahas daftar string karakter tunggal sebagai representasi string yang valid. Mungkin patut membuat meta post (terutama karena saya pikir ini juga muncul pada tantangan terbaru xnor). Saya akan mengatakan tidak untuk saat ini.
Martin Ender
Bagaimana dengan array karakter? Ini sepertinya mengisyaratkan bahwa mereka diizinkan meskipun bahasa tersebut memiliki tipe string yang tepat.
Dennis
@ Dennis Ya, array karakter baik-baik saja, tetapi string singleton seperti mengambil array bilangan bulat [[1], [2], [3]].
Martin Ender
OK, terima kasih sudah menjelaskannya.
Dennis

Jawaban:

3

Jelly , 23 22 21 byte

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

Cobalah online! Perhatikan bahwa dua test case terakhir akan kehabisan memori.

Verifikasi

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

Bagaimana itu bekerja

='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.
Dennis
sumber
12

Python 2, 88 byte

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>'']

Fungsi yang mengambil dalam tiga string dan output hasilnya menjadi STDOUT. Fungsi ini hanya satu melewati string, mengambil karakter yang sesuai dan memperbarui b,csaat kita pergi.

Untuk pengujian (setelah mengganti printdengan return):

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

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

Java 7, 141

Saya pikir masih ada lagi yang bisa saya lakukan dengan ini, tetapi saya harus lari sekarang. Ini hanya iterate / ganti yang sederhana, menjaga indeks dalam A dan 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;}

Putih untuk kesenangan Anda:

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;
}
Geobit
sumber
Whitespacedya, itu benar-benar dapat dibaca
kucing
Bukan begitu? Alasan utama saya menambahkan versi indentasi multi-line adalah untuk menghindari pengguliran horizontal, supaya semuanya dapat dilihat sekaligus. Ruang putih sebaris bukan masalah besar IMO;)
Geobits
[fitur-permintaan] spasi lebih banyak lagi
Alex A.
@AlexA. Ini dia!
Geobits
@ Geobits Simpan byte di akhir jika Anda melakukannyaj<k?a:d
Xanderhall
7

Lua, 121 Bytes

Solusi langsung, gsubmemungkinkan kita untuk mengulang tepat sekali pada setiap karakter dan menggantinya dalam instance string yang baru.

Dibutuhkan input melalui 3 argumen baris perintah dan output string ke 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)

Tidak disatukan

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
Katenkyo
sumber
6

Python 3, 127 byte.

Disimpan 16 byte berkat Katenkyo.

Masih sedikit mengerjakan ini, manusia nastier ini daripada yang saya kira.

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

Penjelasan: Awww ya, rekursi.

Kasus uji:

assert f('abcdeedcba', 'ada', 'BOB') == 'BbcOeedcbB'
assert f('abcdeedcbaabcde', 'ed', '12') == 'abcd1e2cbaabcde'
assert f('012345678901234567890123456789', '42', 'TT') == '0123T5678901T34567890123456789'
assert f('ABC', 'ABCD', '1234') == 'ABC'
Morgan Thrapp
sumber
Memberi +1 untuk bermain golf 50, tapi teruskan! Setidaknya ini harus mengalahkan jawaban Java saya;)
Geobits
7
@ Geobits Ya, saya tidak pernah kalah dari Jawa sebelumnya. Ini adalah rasa malu terbesar saya.
Morgan Thrapp
Saya tidak benar-benar berpengalaman dalam python tetapi all(x in a for x in b)juga memeriksa elemen-elemen dalam b dan a muncul dalam urutan yang sama, atau hanya jika mereka ada di sini?
Katenkyo
@Katenkyo Hanya bahwa mereka semua ada di sana, tetapi pesanan akan diatasi dengan pengiris saat kita kambuh.
Morgan Thrapp
Ok, juga, tidak akan 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 amembuat Anda menghemat beberapa byte?
Katenkyo
5

Python 3.5, 87 byte

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

repl.it untuk memverifikasi semua kasus uji .

Bagaimana itu bekerja

  • '(.*?)'.join(p) membangun pola pencarian yang sesuai dengan urutan yang akan diganti dan apa pun di antara elemen-elemennya.

    Karena quantifiers malas, masing (.*?)- masing akan mencocokkan sesedikit mungkin karakter.

    Untuk polanya ghost, regex yang dibangun adalah g(.*?)h(.*?)o(.*?)s(.*?)t.

  • '\g<%d>'.join(r)%(*range(1,len(r)),) membangun string pengganti, menggunakan pemformatan string.

    Setiap \g<n>mengacu pada n th kelompok ditangkap, seperti \nakan.

    Untuk penggantian 12345, string yang dibuat adalah 1\g<1>2\g<2>3\g<3>4\g<4>5.

  • re.sub(...,...,s,1)melakukan paling banyak satu penggantian dalam string s.

Dennis
sumber
4

Pyth, 27

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

Test Suite

Test suite menghilangkan dua case terakhir karena mereka akan kehabisan memori. Algoritma yang digunakan di sini adalah untuk menemukan semua indeks dari setiap karakter dalam string kedua di string pertama, kemudian menemukan semua urutan yang mungkin dari indeks tersebut dan hanya mengambil yang berada dalam urutan diurutkan. Kemudian gunakan yang pertama ini dalam urutan diurutkan sebagai daftar indeks dalam string pertama untuk memperbarui dengan nilai-nilai dari string ketiga.

Saya merasa harus ada sesuatu yang lebih pendek dari .nM*F...

FryAmTheEggman
sumber
4

MATL , 33 byte

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

Cobalah online!

Penjelasan

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)
Luis Mendo
sumber
3

JavaScript (ES6), 84 byte

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

Penjelasan / Tes

pengguna81655
sumber
3

JavaScript (ES6), 84 76 byte

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

Karena saya yakin ini adalah pekerjaan untuk RegExp.

Sunting: Disimpan 8 byte berkat @ MartinBüttner ♦.

Port jawaban Ruby @ KevinLau mengambil 82 byte:

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

Saya juga mencoba solusi RegExp rekursif tetapi butuh 90 byte:

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

Julia, 89 70 byte

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

Menggunakan indeks iuntuk beralih melalui pola / string pengganti saat kita melangkah. -19 byte terima kasih kepada @Dennis!

Sp3000
sumber
2

C, 98 byte

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

/ * Kode diperluas * /

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

Argumennya adalah: i nput string, o utput buffer, s earch string, r eplacement.

Setelah mengingat dimulainya input dan output, kami menjalankan input, mengganti dan memajukan substitusi setiap kali kami menekan satu. Pada akhirnya, jika kita kehabisan substitusi, kembalikan buffer output, atau input yang tidak dimodifikasi.

/ * Tes * /

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;
}
Toby Speight
sumber
2

R, 76 byte

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

menggunakan sub untuk mengganti pertandingan pertama

Tidak disatukan

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
mnel
sumber
2

C ++, 204 byte

Golf

#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;}

Tidak disatukan

#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;
}
Michelfrancis Bustillos
sumber
Saya tidak berpikir Anda menggunakan stdcukup untuk menjamin penggunaan using namespace std;. Menggunakan std::cin,, std::coutdan std::stringakan menghemat 5 byte karena tampaknya hanya menggunakan namespace itu.
Value Ink
@KevinLau Terima kasih! Anda benar sekali, saya memikirkan itu, tetapi tidak benar-benar menghitung untuk menyadari bahwa itu akan menghemat biaya.
Michelfrancis Bustillos
Oh! Satu hal lagi, karena ini penting. Setelah membaca kode Anda lagi, saya menyadari Anda dengan rakus mengganti kemunculan paling kiri setiap huruf di bdalam a, tetapi surat-surat selanjutnya harus setelah surat sebelumnya juga. (Lihatlah test case 3 dan bandingkan dengan output Anda, saya pikir Anda akan menemukan bahwa kode Anda akan output abc21ed...ketika output yang diharapkan abcd1e2...!)
Value Ink
Dalam input kompilasi ideone C ++ 14 dari "Adregffftd \ nA23 \ nzac \ n" di atas kode 10 menit yang lalu, hasilkan output "zdregffftd" alih-alih "Adregffftd"
RosLuP
2

Retina , 63 byte

.+$
$&¶;$&
+`^(.)(.*¶)(.)([^;]+);(.*?)\1
$2$4$5$3;
A1`
;

G2=`.

Input diambil dalam rangka B, C, A, dipisahkan oleh linefeeds.

Cobalah online.

Martin Ender
sumber
2

Haskell, 87 byte

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

Saya perhatikan kurangnya jawaban Haskell, dan memutuskan untuk memperbaikinya. Ini mendefinisikan fungsi terner !dengan pola urutan-penggantian-string. Coba di sini.

Penjelasan

Fungsi bantu #mengambil daftar xpasangan karakter (pola dan penggantian) dan string y. Jika karakter "pola" dalam xbentuk selanjutnya y, itu mengembalikan daftar kosong dan ydengan masing-masing karakter pola digantikan oleh rekannya. Jika tidak, itu mengembalikan pasangan (x,y). Fungsi !ritsleting pola dan string pengganti menjadi x, berlaku #untuk xdan string ketiga, dan mengembalikan komponen kedua dari hasilnya.

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.

Jika polanya adalah urutan dari string, kode akan berjalan dalam waktu O (n) , membuat satu kali rekursif melewati string dan dengan cepat membangun pengganti dalam proses. Namun, jika polanya bukan urutan, ia berjalan dalam waktu O (2 n ) dalam kasus terburuk. Ini karena pada setiap posisi di mana pola dan string memiliki karakter yang cocok, fungsi memanggil dirinya sendiri untuk memeriksa apakah pola itu sebenarnya sebuah urutan, menemukan itu bukan, dan menyebut dirinya waktu kedua untuk benar-benar menghitung hasilnya.

Zgarb
sumber
2

JavaScript (ES6), 100 95 byte

(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

Ini adalah fungsi JavaScript Lambda yang valid. Output sebagai fungsi return. Dibawa dalam tiga argumen ( a,b,c). Tambahkan f=di awal dan aktifkan like 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")))

Arjun
sumber
Selamat datang di PPCG! Fungsi yang tidak disebutkan namanya umumnya dapat diterima , jadi Anda tidak perlu f=kecuali fungsi Anda bersifat rekursif, tetapi tidak terlihat seperti itu.
Martin Ender
@ MartinBüttner Terima kasih! :) Memperbarui jawaban saya.
Arjun
Sayangnya, ini akan gagal jika a tidak mengandung polanya. Saya juga tidak yakin mengembalikan deretan string dapat diterima.
Dennis
@ Dennis Saya telah memperbarui solusi saya. Saya pikir itu benar sekarang. Maaf atas keterlambatan balasan dan pembaruan. (Saya baru saja memperhatikan komentar Anda, maka penundaan itu)
Arjun
@ MartinEnder Ketika saya sedang melewati semua solusi saya, saya menemukan bahwa yang ini salah. Tapi, saya sudah memperbaikinya sekarang; dan itu lima byte lebih pendek (karena saya telah meninggalkan banyak tempat golf tidak tersentuh; saya adalah pegolf pemula pada waktu itu; bukan berarti saya hebat sekarang, meskipun: p). Maaf karena memposting solusi yang salah.
Arjun
2

C (gcc), 67 62 61 59 byte

f(s,a,b)char*s,*a,*b;{*s==*a?*s=*b++,a++:1;*a&&f(s+1,a,b);}

Cobalah online!

betseg
sumber
1

Oktaf, 97 byte

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;

Iterate atas penggantian untuk menggantikan; temukan kemunculan pertama karakter pertama, temukan karakter berikutnya dalam string yang tersisa, ulangi. Sedikit yang menarik dari ini adalah:

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

Karena ideone masih tidak menerima fungsi dengan nama selain '', saya hanya akan membiarkan sampel dijalankan di sini. Input hanya ditampilkan untuk beberapa kasus uji pertama untuk singkatnya. keyadalah output yang diharapkan, ansadalah output fungsi.

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
gelas kimia
sumber
Tugas-tugas Oktaf itu di tempat-tempat yang tak terduga ( D(t=...)) terus membingungkan saya :-)
Luis Mendo
1
@LuisMendo haha ​​... hampir seperti ... setumpuk! :)
gelas kimia
1

Python 3, 123 Bytes

Pendekatan yang berbeda yang ingin saya bagikan, yang beberapa byte lebih pendek. Tidak ada aturan yang melarang standar library / regex, kan?

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. Ini golf pertama saya. Beri tahu saya tentang masalah / peningkatan apa pun.

Marc J
sumber
1

Pyth, 22 byte

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

Verifikasi semua uji dalam Pyth Compiler .

Latar Belakang

Kami membangun regex dari pola dengan menambahkan $dan menempatkan(.*?) antara semua karakter. Regex ini akan cocok dengan urutan yang akan diganti dan apa pun di antara elemen-elemennya, dan apa pun hingga akhir string.

Karena quantifiers malas, masing (.*?)- masing akan mencocokkan sesedikit mungkin karakter.

Untuk pola hantu, regex yang dibangun adalah g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$.

Jika polanya cocok dengan input, builtin r<str><regex>3akan mengembalikan array yang berisi prematch (semuanya sebelum berikutnya), semua grup yang diambil (semuanya di antara dan setelah berikutnya), dan postmatch (string kosong).

Jika polanya tidak cocok, builtin akan mengembalikan array tunggal yang berisi input asli.

Bagaimana itu bekerja

|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.
Dennis
sumber
1

Jelly , 23 byte

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

Ini dua byte lebih panjang dari jawaban Jelly saya yang lain , tetapi langsung selesai. Cobalah online!

Verifikasi

$ 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

Bagaimana itu bekerja

⁴='-;ç\ñ⁴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.
Dennis
sumber
1

Java 7, 102 byte

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++];}

Detail coba di sini

// 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++];
}
Khaled.K
sumber
1

Julia, 93 90 86 byte

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

Harus menguji secara terpisah jika pertandingan berhasil agak menghancurkan skor. Substitusi akan membutuhkan casting untukBase.SubstitutionString , yang mungkin tidak layak ...

Uji coba

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"
Dennis
sumber
1

Julia, 62 59 58 byte

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

I / O dalam bentuk array karakter.

Verifikasi

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"
Dennis
sumber
1

PHP, 130 109 byte

Saya masih suka lebih pendek; dapat menghemat 3 byte ( ""<) jika Bdijamin tidak mengandung 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;

mengambil argumen dari baris perintah. Jalankan dengan -r.

Mengganti karakter ketika menemukannya;
mencetak salinan jika semua karakter telah diganti; asli yang lain.

Titus
sumber
1

Ruby, 70 64 59 58 byte

Fungsi anonim. Telusuri string auntuk membangun string baru dengan huruf diganti sesuai dengan karakter selanjutnya dib dan c, kemudian jika semua karakter dalam bhabis pada akhirnya, kembalikan string yang baru dibangun, jika tidak kembalikan string asli.

@ histokrat membantu menghemat 6 byte melalui gsub.

Disimpan 1 byte berkat @Cyoce.

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

Cobalah online!

Nilai Tinta
sumber
Anda dapat menyimpan byte dengan menggantinya -1+i+=1dengan~-i+=1
Cyoce
0

Perl, 80 + 1 = 81 byte

Jalankan dengan -pbendera

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

Cobalah online!

Kode secara prosedural menghasilkan pencarian dan mengganti perintah regex, yang kemudian dieksekusi dalam bit kode terakhir.

String ghostpada contoh pertama diubah menjadi string g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), yang berarti gdiikuti oleh 0 atau lebih karakter, diikuti oleh hdiikuti oleh 0 atau lebih karakter, diikuti oleh dll.*? Kuantifikasi berarti bahwa pencarian harus non-serakah dan "melahap" "sesedikit mungkin karakter, daripada pencocokan default sebanyak mungkin.

String 12345kemudian berubah menjadi 1 .$1.2 .$2.3 .$3.4 .$4.5 .$5, yang dievaluasi setelah regex dilakukan. Masing-masing $1,$2,$3,$4,$5sebenarnya adalah referensi kembali ke grup tangkap (dalam tanda kurung) dari string pertama.

Gabriel Benamy
sumber
Saya sarankan kode ini untuk menyimpan beberapa byte: perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'. Datang sendiri dengan saya, tapi itu cukup dekat dengan Anda, jadi saya tidak akan mempostingnya, itu akan menjadi dua jawaban yang sangat dekat, tetapi jangan ragu untuk mengedit milik Anda!
Dada
Baru saja mencobanya karena saya melihatnya terdaftar sebagai pertanyaan "terkait" dengan masalah baru-baru ini. Yang terbaik yang saya dapatkan adalahperl -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;'
Will Crawford
0

Clojure, 113 byte

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

Panggilan dasar reduce, tidak terlalu senang tentang semua yang panjang first, restdan conjfungsi. Berharap bisa melihat pendekatan yang lebih baik.

NikoNyrh
sumber