Kolejność zastąpienia

30

Większość języków ma wbudowaną funkcję wyszukiwania ciągu dla wszystkich wystąpień danego podłańcucha i zastąpienia go innym. Nie znam żadnego języka, który uogólniałby tę koncepcję na (niekoniecznie ciągłe) podsekwencje. To jest twoje zadanie w tym wyzwaniu.

Dane wejściowe będą się składały z trzech łańcuchów A, Ba także C, gdzie Bi Cna pewno, będą miały tę samą długość. Jeśli Bpojawia się jako podsekwencja A, należy go zastąpić C. Oto prosty przykład:

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

Byłoby przetwarzane w następujący sposób:

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

Jeśli istnieje kilka sposobów na znalezienie Bpodsekwencji, należy koniecznie zastąpić skrajnie lewy:

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

To samo dotyczy sytuacji, w Bktórych można je znaleźć w wielu rozłącznych miejscach:

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

Kiedy Bnie pojawia się w A, powinieneś wyjść Aniezmieniony.

Zasady

Jak wspomniano powyżej, wziąć trzy struny A, Ba Cjako wejście i zastąpić lewej najwięcej występowanie Bjako podciąg w Az C, jeśli nie ma żadnych.

Możesz napisać program lub funkcję, pobierając dane wejściowe przez STDIN (lub najbliższą alternatywę), argument wiersza poleceń lub argument funkcji i wypisując wynik przez STDOUT (lub najbliższą alternatywę), wartość zwracaną funkcji lub parametr funkcji (wyjściowej).

Możesz wziąć trzy ciągi znaków w dowolnej spójnej kolejności, którą powinieneś określić w swojej odpowiedzi. Możesz to założyć Bi Cmieć taką samą długość. Wszystkie ciągi będą zawierać tylko znaki alfanumeryczne.

Obowiązują standardowe zasady .

Przypadki testowe

Każdy przypadek testowy jest cztery linie: A, B, Ca następnie wynik.

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

Tabela liderów

Fragment kodu u dołu tego postu generuje tabele wyników na podstawie odpowiedzi a) jako lista najkrótszych rozwiązań dla każdego języka oraz b) jako ogólna tabela wyników.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

## Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:

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

Martin Ender
źródło
Czy lista ciągów jednoznakowych byłaby odpowiednia dla wejścia / wyjścia?
FryAmTheEggman
@FryAmTheEggman Hm, jedyny konsensus, jaki mogę znaleźć, to taki, który nie odnosi się do list ciągów jednoznakowych jako prawidłowych reprezentacji ciągów. Może warto napisać meta post (szczególnie dlatego, że myślę, że pojawiło się to również w ostatnim wyzwaniu xnor). Na razie powiem nie.
Martin Ender,
Co z tablicami postaci? To zdaje się sugerować, że wolno nawet jeśli język ma właściwego typu string.
Dennis,
@Dennis Tak, tablice znaków są w porządku, ale ciągi znaków singleton są jak przyjmowanie tablic liczb całkowitych jako [[1], [2], [3]].
Martin Ender,
OK, dziękuję za wyjaśnienie.
Dennis,

Odpowiedzi:

3

Galaretka , 23 22 21 bajtów

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

Wypróbuj online! Zauważ, że w dwóch ostatnich przypadkach testowych zabraknie pamięci.

Weryfikacja

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

Jak to działa

='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
źródło
12

Python 2, 88 bajtów

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

Funkcja, która przyjmuje trzy ciągi i przekazuje wynik do STDOUT. Ta funkcja po prostu przesuwa jeden ciąg znaków, pobierając odpowiedni znak i aktualizując go w b,cmiarę upływu czasu .

Do badania (po wymianie printz 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
źródło
9

Java 7, 141

Myślę, że mogę coś więcej z tym zrobić, ale na razie muszę uciekać. To tylko prosta iteracja / zamiana, z zachowaniem indeksu w A i 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;}

Biała przestrzeń dla Twojej przyjemności:

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;
}
Geobity
źródło
Whitespacedtak, to całkowicie czytelne
kot
Prawda? Głównym powodem, dla którego dodałem wersję z wieloma wcięciami, jest unikanie przewijania w poziomie, aby wszystko było widoczne jednocześnie. Inline białe spacje nie są aż tak wielkim problemem IMO;)
Geobits 14.04.16
[żądanie funkcji] jeszcze więcej białych znaków
Alex A.
@AlexA. Proszę bardzo!
Geobits
@Geobits Zapisz bajt na końcu, jeśli to zrobiszj<k?a:d
Xanderhall,
7

Lua, 121 bajtów

Proste rozwiązanie gsubpozwala nam iterować dokładnie jeden raz na każdym znaku i zastępować je w nowej instancji ciągu.

Pobiera dane wejściowe za pomocą 3 argumentu wiersza poleceń i wysyła ciąg znaków do 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)

Bez golfa

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
źródło
6

Python 3, 127 bajtów.

Zaoszczędź 16 bajtów dzięki Katenkyo.

Nadal nad tym trochę pracowałem, mężczyzna był o wiele bardziej paskudny, niż się spodziewałem.

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

Objaśnienie: Awww tak, rekurencja.

Przypadki testowe:

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
źródło
+1 za grę w golfa 50 off, ale idź dalej! To musi pokonać przynajmniej moją odpowiedź Java;)
Geobits 13.04.16
7
@Geobits Tak, nigdy wcześniej nie przegrałem z Javą. To moja największa wstyd.
Morgan Thrapp,
Nie jestem zorientowany w Pythonie, ale all(x in a for x in b)sprawdzam również, czy elementy wb oraz a pojawiają się w tej samej kolejności, czy tylko jeśli są tutaj?
Katenkyo,
@Katenkyo Tylko, że wszyscy tam są, ale kolejność jest załatwiana przez krojenie, gdy się powtarzamy.
Morgan Thrapp,
Ok, czy też nie 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 azmusiłbyś do zaoszczędzenia niektórych bajtów?
Katenkyo 13.04.16
5

Python 3.5, 87 bajtów

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

repl.it, aby zweryfikować wszystkie przypadki testowe .

Jak to działa

  • '(.*?)'.join(p) buduje wzorzec wyszukiwania, który pasuje do podsekwencji, która ma zostać zastąpiona, i wszystkiego między jej elementami.

    Ponieważ kwantyfikatory są leniwe, każdy (.*?)dopasuje jak najmniej znaków.

    Dla wzorca ghostkonstruowane wyrażenie regularne to g(.*?)h(.*?)o(.*?)s(.*?)t.

  • '\g<%d>'.join(r)%(*range(1,len(r)),) buduje ciąg zastępujący, używając formatowania ciągu.

    Każda \g<n>odnosi się do n- tej złapanej grupy, tak jak \nby to zrobiła.

    Do zamiany 12345skonstruowany ciąg to 1\g<1>2\g<2>3\g<3>4\g<4>5.

  • re.sub(...,...,s,1)wykonuje najwyżej jedną zamianę w ciągu s.

Dennis
źródło
4

Pyth, 27

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

Pakiet testowy

Zestaw testowy pomija dwa ostatnie przypadki, ponieważ zabraknie im pamięci. Zastosowany tutaj algorytm polega na znalezieniu wszystkich indeksów każdego znaku w drugim ciągu w pierwszym ciągu, a następnie znalezieniu wszystkich możliwych kolejności tych wskaźników i wzięciu tylko tych, które są posortowane. Następnie użyj pierwszego z nich w posortowanej kolejności jako listy indeksów w pierwszym ciągu, aby zaktualizować wartości z trzeciego ciągu.

Czuję, że powinno być coś krótszego niż .nM*F...

FryAmTheEggman
źródło
4

MATL , 33 bajty

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

Wypróbuj online!

Wyjaśnienie

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
źródło
3

JavaScript (ES6), 84 bajtów

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

Wyjaśnienie / test

użytkownik 81655
źródło
3

JavaScript (ES6), 84 76 bajtów

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

Ponieważ byłem pewien, że to zadanie dla RegExp.

Edycja: Zapisano 8 bajtów dzięki @ MartinBüttner ♦.

Port odpowiedzi Ruby @ KevinLau zajął 82 bajty:

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

Próbowałem także rekurencyjnego rozwiązania RegExp, ale zajęło to 90 bajtów:

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

Julia, 89 70 bajtów

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

Korzysta z indeksu ido iteracji po łańcuchach wzorca / zamiany. -19 bajtów dzięki @Dennis!

Sp3000
źródło
2

C, 98 bajtów

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

/ * Rozszerzony kod * /

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

Argumentami są: i nput string, o bufor danych, s earch string, r eplacement.

Po zapamiętaniu początku wejścia i wyjścia przechodzimy przez dane wejściowe, zastępując i przyspieszając podstawienie za każdym razem, gdy trafimy na jeden. Na koniec, jeśli zabraknie podstawień, zwróć bufor wyjściowy, w przeciwnym razie niezmodyfikowane dane wejściowe.

/ * Testy * /

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
źródło
2

R, 76 bajtów

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

wykorzystuje sub do zastąpienia pierwszego dopasowania

Bez golfa

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
źródło
2

C ++, 204 bajty

Grał w golfa

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

Bez golfa

#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
źródło
Nie sądzę, że używasz stdwystarczająco dużo, aby uzasadnić użycie using namespace std;. Użycie std::cin, std::couti std::stringpozwoli zaoszczędzić 5 bajtów, ponieważ wydaje się, że są to jedyne zastosowania tej przestrzeni nazw.
Wartość tuszu
@KevinLau Thanks! Masz rację, pomyślałem o tym, ale tak naprawdę nie liczyłem, że to uratuje znaki.
Michelfrancis Bustillos
O! Jeszcze jedna rzecz, ponieważ jest ważna. Po raz kolejny czytając kod zdałem sobie sprawę, jesteś łapczywie zastępując lewy-większość występowania każdej litery w ciągu bw a, ale późniejsze litery muszą być po wcześniejszych pism, jak również. (Spójrz na przypadek testowy 3 i porównaj go z wynikami, myślę, że zauważysz, że Twój kod wyświetliłby się, abc21ed...gdy oczekiwany wynik to abcd1e2...!)
Wartość tuszu
W danych wejściowych kompilatora ideone C ++ 14 „Adregffftd \ nA23 \ nzac \ n” powyżej kodu 10 minut temu wygeneruj dane wyjściowe „zdregffftd” zamiast „Adregffftd”
RosLuP
2

Siatkówka , 63 bajty

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

G2=`.

Wejście zostało zrobione w celu B, C, A, oddzielone karetki.

Wypróbuj online.

Martin Ender
źródło
2

Haskell, 87 bajtów

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

Zauważyłem brak odpowiedzi Haskella i postanowiłem to naprawić. Definiuje funkcję potrójną !z ciągiem argumentów wzorzec-zamiennik-ciąg. Wypróbuj tutaj.

Wyjaśnienie

Funkcja pomocnicza #pobiera listę xpar znaków (wzorzec i zamiennik) oraz ciąg znaków y. Jeśli znaki „wzorzec” w xformie są podsekwencją y, zwraca pustą listę, a ykażdy znak wzorca zastępuje się swoim odpowiednikiem. W przeciwnym razie zwraca parę (x,y). Funkcja !zamyka wzorce i łańcuchy zastępujące x, stosuje się #do xtrzeciego łańcucha i zwraca drugi składnik wyniku.

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.

Jeśli wzorzec jest podciągiem łańcucha, kod działa w czasie O (n) , wykonując jeden cykl rekurencyjny przez ciąg i zachłannie konstruując zamianę w tym procesie. Jeśli jednak wzorzec nie jest podsekwencją, w najgorszym przypadku działa w czasie O (2 n ) . Wynika to z faktu, że w każdej pozycji, w której wzorzec i łańcuch mają pasujący znak, funkcja wywołuje samą siebie, aby sprawdzić, czy wzorzec jest faktycznie podsekwencją, dowiaduje się, że nie jest, i wywołuje się po raz drugi w celu obliczenia wyniku.

Zgarb
źródło
2

JavaScript (ES6), 100 95 bajtów

(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

To jest poprawna funkcja JavaScript Lambda. Wyjścia jako funkcja return. Pobiera trzy argumenty ( a,b,c). Dodaj f=na początku i wywołaj jak 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
źródło
Witamy w PPCG! Funkcje nienazwane są ogólnie akceptowane , więc nie potrzebujesz, f=chyba że twoja funkcja jest rekurencyjna, ale tak nie wygląda.
Martin Ender
@ MartinBüttner Dzięki! :) Zaktualizowałem moją odpowiedź.
Arjun
Niestety to się nie powiedzie, jeśli a nie będzie zawierało wzorca. Nie jestem również pewien, czy zwracanie tablicy ciągów jest dopuszczalne.
Dennis
@Dennis Zaktualizowałem swoje rozwiązanie. Myślę, że teraz jest poprawne. Przepraszamy za tak późną odpowiedź i aktualizację. (Właśnie zauważyłem twój komentarz, stąd opóźnienie)
Arjun
@MartinEnder Podczas przeglądania wszystkich moich rozwiązań stwierdziłem, że to było nieprawidłowe. Ale teraz to poprawiłem; i jest o pięć bajtów krótszy (odkąd pozostawiłem wiele nietkniętych miejsc do gry w golfa; byłem wtedy początkującym golfistą; ale nie to, że teraz jestem świetny: p). Przepraszamy za opublikowanie niewłaściwego rozwiązania.
Arjun
2

C (gcc), 67 62 61 59 bajtów

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

Wypróbuj online!

betseg
źródło
1

Oktawa, 97 bajtów

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;

Powtórz podsekwencję, aby zastąpić; znajdź pierwsze wystąpienie pierwszego znaku, znajdź następny znak w pozostałym ciągu, powtórz. Ciekawym tego jest:

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

Ponieważ ideone wciąż nie akceptuje funkcji o nazwach innych niż „”, zostawię tutaj próbkę. Dane wejściowe są wyświetlane tylko dla pierwszych kilku przypadków testowych dla zwięzłości. keyjest oczekiwanym wyjściem, ansjest wyjściem funkcji.

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
zlewka
źródło
Te zadania Octave w nieoczekiwanych miejscach ( D(t=...)) wciąż mnie zastanawiają :-)
Luis Mendo
1
@LuisMendo haha ​​... to prawie jak ... stos! :)
zlewka
1

Python 3, 123 bajtów

Inne podejście, którym chciałem się podzielić, czyli kilka bajtów krótszych. Nie ma żadnych reguł w stosunku do standardowej biblioteki / wyrażenia regularnego, prawda?

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. To jest mój pierwszy golf. Daj mi znać o wszelkich problemach / ulepszeniach.

Marc J
źródło
1

Pyth, 22 bajty

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

Sprawdź wszystkie przypadki testowe w kompilatorze Pyth .

tło

Budujemy wyrażenie regularne na podstawie wzoru, dodając $i umieszczając(.*?) między wszystkimi znakami. Wyrażenie regularne będzie pasować do podsekwencji, która ma zostać zamieniona, i wszystkiego między jej elementami i wszystkiego aż do końca łańcucha.

Ponieważ kwantyfikatory są leniwe, każdy (.*?)dopasuje jak najmniej znaków.

Dla ducha wzorca skonstruowane wyrażenie jest g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$.

Jeśli wzorzec pasuje do wejścia, wbudowane r<str><regex>3 zwróci tablicę zawierającą przedmowę (wszystko przed podsekwencją), wszystkie przechwycone grupy (wszystko pomiędzy i po podsekwencji) oraz postmatch (pusty ciąg).

Jeśli wzorzec nie pasuje, wbudowane zwróci tablicę singletonów zawierającą oryginalne dane wejściowe.

Jak to działa

|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
źródło
1

Galaretka , 23 bajty

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

To dwa bajty dłużej niż moja inna odpowiedź na galaretkę , ale kończy się natychmiast. Wypróbuj online!

Weryfikacja

$ 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

Jak to działa

⁴='-;ç\ñ⁴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
źródło
1

Java 7, 102 bajty

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

Szczegółowe spróbuj tutaj

// 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
źródło
1

Julia, 93 90 86 bajtów

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

Konieczność osobnego przetestowania, czy mecz był udany, niszczy wynik. Zmiana wymagałaby rzutowania naBase.SubstitutionString , co prawdopodobnie nie jest tego warte ...

Testowe uruchomienie

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
źródło
1

Julia, 62 59 58 bajtów

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

I / O ma postać tablic znaków.

Weryfikacja

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
źródło
1

PHP, 130 109 bajtów

Nadal chciałbym być krótszy; można zapisać 3 bajty ( ""<), jeśli Bgwarantuje się, że nie zawiera 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;

pobiera argumenty z wiersza poleceń. Uruchom z -r.

Zastępuje znaki, gdy je znajdzie;
drukuje kopię, jeśli wszystkie znaki zostały zastąpione; oryginał inny.

Tytus
źródło
1

Ruby, 70 64 59 58 bajtów

Funkcja anonimowa. Przejść przez ciąg azbudować nowy ciąg z literami zastąpione zgodnie do następnego znaku w bi c, następnie, jeśli wszystkie znaki wb są wyczerpane w końcu zwróci nowo skonstruowany ciąg, w przeciwnym razie zwraca oryginalny łańcuch.

@histocrat pomógł zaoszczędzić 6 bajtów przez gsub .

Zapisano 1 bajt dzięki @Cyoce.

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

Wypróbuj online!

Wartość tuszu
źródło
Można zapisać bajt zastępując -1+i+=1z~-i+=1
Cyoce
0

Perl, 80 + 1 = 81 bajtów

Uruchom z -pflagą

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

Wypróbuj online!

Kod proceduralnie generuje polecenie wyszukiwania i zamiany wyrażenia regularnego, które następnie wykonuje w ostatnim bicie kodu.

Łańcuch ghostw pierwszym przykładzie zostaje zamieniony na łańcuch g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), co oznacza, że gnastępuje 0 lub więcej znaków, po których hnastępuje 0 lub więcej znaków, a następnie itd. *?Kwantyfikator oznacza, że ​​wyszukiwanie nie powinno być zachłanne i „pożerać” ”jak najmniej znaków, zamiast domyślnego dopasowywania jak największej liczby znaków.

Następnie ciąg 12345zostaje przekształcony w 1 .$1.2 .$2.3 .$3.4 .$4.5 .$5, który jest oceniany po wykonaniu wyrażenia regularnego. Każda z nich $1,$2,$3,$4,$5jest faktycznie odniesieniem do grupy przechwytywania (w nawiasach) od pierwszego ciągu.

Gabriel Benamy
źródło
Proponuję ten kod, aby zaoszczędzić kilka bajtów: perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'. Przyszedłem z tym sam, ale jest dość blisko ciebie, więc nie opublikuję tego, to byłyby dwie bardzo bliskie odpowiedzi, ale możesz edytować swoją!
Dada,
Właśnie spróbowałem, ponieważ widziałem to jako „związane” pytanie do ostatniego problemu. Najlepsze, co dostałem, toperl -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 bajtów

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

Podstawowym reduce, nie jest zbyt zadowolony z tych wszystkich, długo first, resti conjwywołań funkcji. Mając nadzieję na lepsze podejście.

NikoNyrh
źródło