Наступна заміна


30

Більшість мов оснащені вбудованою функцією пошуку рядка для всіх випадків даної підрядки та заміни їх на інші. Я не знаю жодної мови, яка б узагальнювала цю концепцію (не обов'язково суміжну) підпорядкованість. Отже, це ваше завдання в цьому виклику.

Вхід буде складатися з трьох рядків A, Bі 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це не відображається в A, ви повинні виводити його Aбез змін.

Правила

Як було зазначено вище, взяти три рядки A, Bі в Cякості вхідних даних і замінити саме ліве входження в Bякості підпослідовності в Aс C, якщо є.

Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).

Ви можете взяти три рядки в будь-якому послідовному порядку, який слід вказати у своїй відповіді. Можна вважати , що Bі Cмають однакову довжину. Усі рядки містять лише буквено-цифрові символи.

Діють стандартні правила .

Випробування

Кожен тест чотири лінії: A, B, 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

Таблиця лідерів

Фрагмент стека внизу цієї публікації генерує таблицю лідерів з відповідей а) як список найкоротших варіантів для кожної мови та б) як загальний таблиця лідерів.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

## Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

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

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш результат становить суму двох файлів або ви хочете окремо вказати штрафні санкції для перекладача), переконайтесь, що фактичний результат - це останнє число у заголовку:

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

Ви також можете зробити ім'я мови посиланням, яке з’явиться у фрагменті:

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


Буде добре список рядків з одним символом для введення / виводу?
FryAmTheEggman

@FryAmTheEggman Гм, єдиний консенсус, який я можу знайти, це такий, який не розглядає списки односимвольних рядків як дійсні представлення рядків. Можливо, варто зайняти метапост (особливо тому, що я думаю, що це також з’явилося в останньому виклику xnor). Я зараз скажу "ні".
Мартін Ендер

Що з масивами символів? Це , здається, має на увазі , що вони дозволили навіть якщо мова має правильний тип рядка.
Денніс

@Dennis Так, масиви символів є нормальними, але одиночні рядки - це як прийняти масив цілих чисел як [[1], [2], [3]].
Мартін Ендер

Добре, дякую за очищення.
Денніс

Відповіді:


3

Желе , 23 22 21 байт

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

Спробуйте в Інтернеті! Зауважте, що в останніх двох тестових випадках не вистачить пам'яті.

Перевірка

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

Функція, яка бере три струни і виводить результат в STDOUT. Функція просто робить один прохід по рядку, приймаючи відповідну таблицю та оновлюючи її b,cпо ходу.

Для тестування (після заміни printз return):

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

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

9

Ява 7, 141

Я думаю, що я можу зробити з цим ще щось, але зараз я повинен бігти. Це просто проста ітерація / заміна, зберігаючи індекс в А і В.

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 для вашого задоволення:

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так, це повністю читабельно
кіт

Чи не все-таки? Основна причина, за якою я додаю багаторядкову відрізну версію, - це уникати горизонтальної прокрутки, просто так це можна побачити відразу. Вбудований простір в Інтернеті не такий вже й великий ІМО;)
Геобіт

[функція-запит] ще більше пробілів
Алекс А.


@Geobits Збережіть байт в кінці, якщо ви це зробитеj<k?a:d
Xanderhall

7

Луа, 121 байт

Безпосереднє рішення gsubдозволяє нам ітераціювати рівно один раз на кожному символі та замінювати їх у новому екземплярі рядка.

Він бере вхід через 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 байт.

Збережено 16 байт завдяки Katenkyo.

Ще трохи працюючи над цим, людина була такою неприємнішою, ніж я думав, що це буде.

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'

+1 для гольфу 50 знижок, але продовжуйте! Це потрібно принаймні перемогти мою відповідь на Java;)
Геобіт

7
@Geobits Так, я ніколи раніше не програвав Java. Це моя найбільша ганьба.
Морган Трапп

Я насправді не розбирається в python, але all(x in a for x in b)також перевіряє, що елементи в b і a з’являються в тому ж порядку, або лише якщо вони тут?
Katenkyo

@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змусить вас зберегти кілька байт?
Katenkyo

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)виконує щонайменше одну заміну в рядку s.


4

Піта, 27

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

Тестовий сюїт

Тестовий набір опускає два останні випадки, оскільки у них не вистачить пам’яті. Тут використаний алгоритм - знайти всі індекси кожного символу у другому рядку в першому рядку, а потім знайти всі можливі впорядкування цих індексів і взяти лише ті, які відсортовані. Потім використовуйте перший із них у відсортованому порядку як список індексів у першому рядку для оновлення зі значеннями з третього рядка.

Я відчуваю, що має бути щось коротше, ніж .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.

Редагувати: Збережено 8 байт завдяки @ MartinBüttner ♦.

Порт відповіді Рубі @ KevinLau взяв 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для повторення через рядки шаблону / заміни. -19 байт завдяки @Dennis!


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

Аргументи: i nput string, o utput buffer, s earch string, 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::cin, std::coutта std::stringзбереже 5 байт, оскільки вони, здається, є єдиним використанням цього простору імен.
Значення чорнила

@KevinLau Дякую! Ви дуже правильні, я думав про це, але насправді не розраховував, що це врятує символи.
Michelfrancis Bustillos

Ой! Ще одне, адже це важливо. Після повторного ознайомлення з вашим кодом я зрозумів, що ви жадібно замінюєте найчастіше ліву частину кожної літери bв a, але пізніші букви також повинні бути після попередніх літер. (Подивіться на тестовий випадок 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#)

Я помітив відсутність відповіді Хаскелла і вирішив це виправити. Це визначає потрійну функцію !з аргументом порядку замовлення шаблону-заміни-рядка. Спробуйте тут.

Пояснення

Допоміжна функція #займає список xпар символів (візерунок та заміна) та рядок y. Якщо символи "шаблону" xутворюють yпідпорядкування, він повертає порожній список і yз кожним символом шаблону замінюється його аналогом. В іншому випадку він повертає пару (x,y). Функція !перетягує рядки шаблону та заміни x, застосовується #до xтретьої рядки та повертає другий компонент результату.

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) час, роблячи один рекурсивний прохід через рядок і жадібно будуючи заміну в процесі. Однак, якщо шаблон не є підрядчиком, він працює в 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. Виходи як функція return. Береться за три аргументи ( 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 Я оновив своє рішення. Я думаю, це зараз правильно. Вибачте за таку несвоєчасну відповідь та оновлення. (Я щойно помітив ваш коментар, звідси і затримка)
Арджун

@MartinEnder Поки я переглядав усі свої рішення, я виявив, що це неправильно. Але, я зараз це виправив; і це на п’ять байтів коротше (оскільки я залишив багато недоторканих місць; я був початківцем гольфістом у той час; не те, що зараз я чудовий: p). Вибачте за повідомлення про неправильне рішення.
Арджун


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

Пітон 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

Піт, 22 байти

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

Перевірте всі тестові випадки в компіляторі Pyth .

Фон

Будуємо регекс із шаблону, додаючи а $та розміщуючи(.*?) між усіма символами. Цей регулярний вираз буде відповідати підстановці, яку потрібно замінити, і будь-що між її елементами та будь-чим до кінця рядка.

Оскільки кількісні показники ліниві, кожен (.*?)буде відповідати якомога менше символів.

Для візерунка-привида побудований регулярний вираз 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 , але він закінчується миттєво. Спробуйте в Інтернеті!

Перевірка

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

Введення / виведення у формі символьних масивів.

Перевірка

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щоб створити нову рядок із літерами, заміненими відповідно до наступного символу в, bа cпотім, якщо всі символи в bкінці вичерпані, поверніть щойно побудований рядок, інакше поверніть початковий рядок.

@histocrat допомогло зберегти 6 байт через gsub.

Збережено 1 байт завдяки @Cyoce.

->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у першому прикладі перетворюється на рядок g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), що означає g0 або більше символів, а hпотім 0 ​​або більше символів, далі і т.д.*? кванторного означає , що пошук повинен бути не жадібним і «Gobble "якомога менше символів, замість того, щоб за замовчуванням відповідати якомога більше.

Потім рядок 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."/"'. Придумав це сам, але він досить близький до вашого, тому я його не публікую, це були б дві дуже близькі відповіді, але сміливо редагуйте свої!
Дада

Я просто пішов на це, бо я бачив, що це перелічено як "пов'язане" питання з недавньою проблемою. Найкраще, що я отримав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, не дуже радий всіх тих , хто довго first, restі conjвиклики функцій. Сподіваючись побачити кращий підхід.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.