Растягивать слова

32

Напишите программу или функцию, которая дублирует буквы в слове, чтобы все дублированные буквы, расположенные слева направо в слове, образовывали входной массив.

Например:

input: chameleon, [c,a,l,n]
output: cchaamelleonn

вход

  • Начальное слово (например chameleon)
  • Массив символов ( [c,a,l,n]) или строка для представления array ( caln), или что-то подобное
  • Ввод может быть через параметры функции, STDIN или языковые эквиваленты
  • Все входные данные будут состоять из строчных букв (az)

Выход

  • Измененное слово

  • Если есть несколько решений, любое может быть напечатано

    input: banana [n,a]  
    possible outputs: bannaana, banannaa
                         |-|---------|-|--->[n,a]
    
  • Вы можете предположить, что входное слово (не обязательно массив) будет иметь буквы в массиве (по порядку)

  • Вы также можете предположить, что входные данные не имеют одинаковых последовательных букв (НЕ apple, geek, green, glass, door ...)

Примеры

input: abcdefghij, [a,b,c]
output: aabbccdefghij

input: lizard, [i,a,r,d]
output: liizaarrdd

input: coconut, [c,o]
ouput: ccooconut or coccoonut or ccocoonut

input: onomatopoeia, [o,o,a,o,o]
output: oonoomaatoopooeia

input: onomatopoeia, [o,a,o]
output: oonomaatoopoeia or onoomaatoopoeia or oonomaatopooeia etc.

Самая короткая программа выигрывает!

Таблица лидеров (спасибо Мартину Бюттнеру за фрагмент)

Стрейч маньяк
источник
@AlexA. только один экземпляр, потому что иначе массив, образованный дублирующимися буквами, был бы [c,o,c,o], а не [c,o].
Стрейч Маньяк
Да, извините, прочитав это снова, это очевидно. Спасибо.
Алекс А.
2
Увидев, что на этот вопрос получено довольно много ответов, и на многих языках, вы были бы заинтересованы в добавлении фрагмента списка лидеров ? Если так, я с радостью отредактирую его и исправлю ответы, которые не используют требуемый формат заголовка.
Мартин Эндер
@ MartinBüttner Я забыл об этом! Добавлен. Я должен был изменить #answer-listи #language-listширину , чтобы 50%избежать дублирования столбцов в вашем фрагменте кода.
Стрейч Маньяк
1
Уточнение (см. Мой bash+ sedответ): Это незаконно для banana, na=> baannana? Я полагал, что «Вы можете предположить, что все входные данные будут иметь буквы в массиве (по порядку)», предназначенные для того , чтобы разрешать , но не требовать , ответы для последовательной обработки обоих списков, но @manatwork интерпретировал это по-разному.
Тоби Спейт

Ответы:

5

Pyth, 14 байт

s+L&@d<Q1.(QZz

Демонстрация.

Стиль ввода:

banana
["b","a","n","a"]

Объяснение:

s+L&@d<Q1.(Q0z
                  Implicit: z = input(); Q = eval(input())
 +L          z    Map (lambda d) over z, adding the result to each character.
    @d<Q1         Intersection of d with Q[:1], up to the first element of Q.
   &              Logical and - if the first arg is truthy, evaluate and
                  return the second arg, otherwise return first arg.
         .(Q0     Q.pop(0)
                  The addition will either be the empty string, for the empty
                  intersection, or the character that was Q[0] otherwise.

s                 Concatenate and print.
isaacg
источник
43

Brainfuck, 46 45 (63 с печатными символами на входе)

Совместим с bff Алекса Панкратова (интерпретатор brainfuck, используемый на SPOJ и ideone) и BFI Томаса Корта (используется на Anarchy Golf).

Версия для печати сначала берет массив в виде строки, затем следует вкладка, за которой следует начальная строка без завершающей строки.

Демонстрация на идеоне.

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

Мы можем сохранить несколько байтов, используя \x00вместо табуляции разделитель:

,[>,]
<[<]
<,+
[
  -.
  [>+>-<<-]
  >>
  [
    <[>+<-]
  ]
  <[.[-]]
  ,+
]
Митч Шварц
источник
22
Это чувство, когда BF короче, чем мой код Python .. :(
Kade
6
Я обычно не забочусь о Brainfuck, но это потрясающе!
Денис
Это прекрасно.
Джошпаррон
14

CJam, 15 байтов

rr{_C#)/(C@s}fC

Попробуйте онлайн.

Как это работает

rr              e# Read two whitespace-separated tokens from STDIN.
  {         }fC e# For each character C in the second string.
   _            e#   Duplicate the first string.
    C#          e#   Compute the index of the character in the string.
      )/        e#   Add 1 and split the string in slice of that size.
        (       e#   Shift out the first slice.
         C      e#   Push the character.
          @     e#   Rotate the remainder of the string in top of the stack.
           s    e#   Stringify (concatenate the slices).
Деннис
источник
Это битва CJams! У вас и у Sp оба есть 15-байтовые ответы CJam, и 15 в настоящее время самые короткие. :)
Алекс А.
3
@AlexA. Просто подожди Пайфа. Ты просто подожди ...
Sp3000
2
Похоже, тебе лучше выучить Pyth. ;)
Алексей Александрович
12

C, 62 байта

f(char*s,char*c){while(*s-*c||putchar(*c++),*s)putchar(*s++);}

Ну, это на удивление конкурентно.

Мы определяем функцию, f(char*, char*)которая принимает строку в качестве первого ввода и массив символов для дублирования в качестве второго ввода.

Некоторый тестовый код:

int main (int argc, char** argv) {
    f("onomatopeia", "oao");
    return 0;
}

Какие отпечатки:

oonomaatoopeia

Попробуйте онлайн !

Если допустимо передавать макрос, а не функцию, следующее #define g(s,c)- это всего лишь 58 байтов , но оно требует sи cдолжно быть фактическим указателем:

#define g(s,c)while(*s-*c||putchar(*c++),*s)putchar(*s++);
BrainSteel
источник
1
Спасибо, что заставили меня посмотреть оператор запятой . Это полезно!
Олифаунт - восстановить Монику
11

CJam, 15 байтов

rr{:X/(XX+@X*}/

Альтернативный подход CJam. Попробуйте онлайн

объяснение

Для каждого символа во второй строке мы делаем две вещи.

  1. Разделить текущий суффикс строки на символ, например "beeper" "e" -> ["b" "" "p" "r"]

  2. Разъединяет первую строку в массиве, вставляет два символа, затем воссоединяет остальную часть массива с символом, например "b" "ee" "eper". Последняя строка - это новый суффикс.

Sp3000
источник
9

Сетчатка, 33 байта

Больше информации о Retina.

+`(?=(.))(((.)(?<!\4.))+\n)\1
$1$2

Это предполагает две строки в STDIN, разделенные новой строкой.

For counting purposes, each line goes into a separate file, \n should be replaced with an actual newline character (0x0A). If you actually want to test this, it's more convenient to put this in a single file where \n remains as it is and then invoke Retina with the -s option before passing the file.

Explanation

(Outdated... I managed to get rid of the marker... I'll update this later.)

Each pair of lines is a regex substitution (first line the pattern, second line the substitution).

^
#

This puts a # as a marker at the start of the input string.

+`#(.*?(.))(.*\n)\2
$1$2#$3

This finds the first letter in the input (after the marker) corresponding to the next letter to be duplicated, duplicates that letter, moves the marker behind it, and drops the first character of the second string. The +` at the front tells Retina to do this repeatedly until the string stops changing (in this case, because the second string is empty and all required letters have been duplicated).

#
<empty>

Finally, we clean up the string by dropping the marker.

Martin Ender
источник
2
I figured that retina would have a nice solution, and I was right, because you found one. Also, when I first skimmed your description, I read the end as "we clean up the string by dropping the mic."
mbomb007
@mbomb007 I was hoping to get rid of the "mic" by only duplicating individual letters that don't have any duplicates after them, but I can't do it in less than 33 bytes. (There's a broken 28 byte version in the revision history.)
Martin Ender
@mbomb007 FYI, I did manage to remove the marker now, but the byte count is still the same. This still looks golfable though.
Martin Ender
As an aside, I just realized that Retina doesn't have a page on esolangs.org
mbomb007
@mbomb007 Yes, I'm aware. I'll probably add one after I've implemented a few of the more important outstanding features.
Martin Ender
8

Python, 61

def f(s,l):b=s[:1]==l[:1];return s and-~b*s[0]+f(s[1:],l[b:])

A greedy recursive solution. Saves to b whether the first letter of the string s is the first letter of the string l of letters to double. If so, take one of that letter and prepend it to the recursive call with the rest of s, removing the first element from l. If not b, do the same but don't double the letter and don't remove from l.

The code checks s[:1]==l[:1] rather than s[0]==l[0] to avoid an index-out-of-bounds error when s or l is empty.

xnor
источник
6

Prolog, 95 83 79 56 bytes

d([A|S],H):-put(A),H=[A|T],put(A),d(S,T);d(S,H).
d(_,_).

Example:

d(`chameleon`,`caln`).

returns

cchaamelleonn

Edit: Saved 4 bytes thanks to Oliphaunt

Edit2: Saved 20 bytes using the deprecated put/1 SWI-Prolog predicate instead of writef. Saved one byte replacing the recursion end predicate d([],_). to d(_,_).. Won't work if the ordering of the two definitions of d is swapped though, but we don't care about that in golfed code. Saved another 2 bytes removing the parenthesis around H=[A|T],put(A),d(S,T)

Fatalize
источник
1
I'm not really sure why this got downvoted. Maybe add some explanation to your code?
Alex A.
1
You can save four bytes by unifying implicitly: H=[A|T]. Also, why not make it a little more readable by replacing the spaces with newlines?
Oliphaunt - reinstate Monica
@Oliphaunt Thanks for the suggestion, I didn't see this slight optimization after I originally modified my code to use the H=[A|T] clause.
Fatalize
5

Python 2, 83 74 72 65 Bytes

No real special tricks here. x is the string, y is the array of characters that are duplicated. To clarify if this doesn't copy properly, the first indentation level is a space, the next is a tab.

Edit 1: Saved 9 bytes by using string manipulation instead of pop().

Edit 2: Saved 2 bytes by using -~ to increment g by 1.

Edit 3: Saved 7 bytes by using y[:1] trick, thanks to xnor for this!

def f(x,y,s=''):
 for c in x:g=y[:1]==c;s+=c*-~g;y=y[g:]
 print s

Check it out here.

Properly formatted and explained:

def f(x,y,s=''):           # Defining a function that takes our input,
                           # plus holds a variable we'll append to.
  for c in x:              # For every character in 'x', do the following:
    g = y[:1] == c         # Get the first element from the second string, will
                           # return an empty string if there's nothing left.
                           # Thanks to xnor for this trick!
    s += c * -~g           # Since int(g) would either evaluate to 0 or 1, we
                           # use the -~ method of incrementing g to multiply
                           # the character by 1 or 2 and append it to 's'
    y = y[g:]              # Again, since int(g) would either evaluate to 0
                           # or 1, use that to cut the first value off y, or
                           # keep it if the characters didn't match.
  print s                  # Print the string 's' we've been appending to.
Kade
источник
"You may assume that all inputs will have the letters in the array (in order)." That should save you quite a few bytes.
mbomb007
2
You can get the first element from a possibly-empty string as y[:1].
xnor
I now realize that you can't save as many as I thought because of how you're doing it with y=y[g:], so "quite a few" is quite an exaggeration.
mbomb007
@Vioz- I was thinking y[:1]==c. Does that work?
xnor
@xnor Yes, it does if I take the letters that need replacing instead. Thanks!
Kade
5

Excel VBA, 110 bytes

This is my first entry to CodeGolf so I hope this is ok.

You enter the input word in A1 and then the letters to be replaced in B1 and the resulting word is displayed in a message box.

w = Cells(1, 1)
l = Cells(2, 1)
For i = 1 To Len(w)
x = Left(w, 1)
R = R + x
If InStr(l, x) > 0 Then
R = R + x
End If
w = Right(w, Len(w) - 1)
Next
MsgBox R
Wightboy
источник
2
Если VBA не чувствителен к отступам, вы можете избавиться от всех отступов и сэкономить несколько байтов. Я думаю, что вы также можете избавиться от всех пробелов после запятых и вокруг операторов. Должно сэкономить вам несколько байтов.
Фонд Моника судебный процесс
@QPaysTaxes Thanks for your edit. I pressed rollback just to see what it would do. Not sure if that made you lose points or something for your edit?
Wightboy
Nope, I still have the +2, though I did get confused for a bit. You might want to roll back again; at least according to three highish-rep people, it was a good edit.
Fund Monica's Lawsuit
@QPaysTaxes I agree I liked the edit. Think I just rolledbacked one too many times.
Wightboy
I can't tell. Mobile doesn't exactly display things nicely. Ultimately, though, what matters is the code, not the formatting.
Fund Monica's Lawsuit
4

Haskell, 42 bytes

(a:b)#e@(c:d)|a==c=a:a:b#d|1<2=a:b#e
a#_=a

Usage example:

*Main> "coconut" # "co"
"ccooconut"
*Main> "lizard" # "iard"
"liizaarrdd"
*Main> "onomatopoeia" # "ooaoo"
"oonoomaatoopooeia"

How it works:

If one string is empty, the result is the first string. Else: if the first characters of the strings match, take it two times and append a recursive call with the tails of the strings. If the characters don't match, take the first character of the first string and append a recursive call with the tail of the first string and the same second string.

nimi
источник
4

Pyth, 18 17 bytes

sm?+d.(QZqd&QhQdz

Live demo.

Saved 1 byte thanks to @Jakube.

Explanation:

                z  Read the first line of input.
 m                 For each character in that line
  ?      qd&QhQ    If (?) the first char of the stretch list (`&QhQ`) 
                   and the current character are equal,
   +d.(QZ          Then double the current character and pop an element off
                   the stretch list.
               d   Otherwise, just return the same character.
s                  Join all the characters together.

Original version:

jkm?+d.(QZqd&QhQdz

Live demo for original.

kirbyfan64sos
источник
4

Javascript, 47 bytes

(a,b)=>a.replace(/./g,d=>b[0]!=d?d:d+b.shift())

Taking advantage of some ES6 features.

Cereal
источник
1
Does this work correctly for onomatopoeia, oao?
Alex A.
1
@AlexA. Выходы: «оооомаатоопооэаа». Я понимаю. Исправлю
Хлопья
Исправлено, я думаю. Добавлено много персонажей :(
Cereal
Вместо того b.indexOf(d)==0, чтобы попробовать~b.search(d)
Исмаэль Мигель
@IsmaelMiguel searchприменим только к строкам. Пришлось изменить b на массив
Cereal
3

Pyth, 16 байт

u|pH<GJxGH>GJwz

Попробуйте онлайн: демонстрация

Это довольно глупо. Языки, основанные на стеке, могут иметь здесь преимущество.

объяснение

                   implicit: z = 1st input line, w = 2nd
u             wz   reduce, start with G = z
                   for each H in w, update G to:
        xGH          index of H in G
       h             +1
      J              store in J
    <GJ              substring: G[:J] (everything before index J)
  pH                 print substring then H (without newlines)
 |                   afterwards (actually or, but p always returns 0)
           >GJ       substring: G[J:] (everything from index J to end)
                     update G with ^
                   afterwards implicitly print the remainder G
Jakube
источник
@isaacg Помощь? Там должно быть что-то короче ...
Jakube
И более элегантно ;-)
Якуб
1
Получил это в 14 - 1 меньше, чем CJam - лучшее место, чтобы быть.
Исаак
3

JavaScript ES6, 47 байт

(w,s)=>w.replace(/./g,c=>c==s[0]?c+s.shift():c)

Предполагается, что sмассив["c","a","l","n"]

Shmiddty
источник
2

> <> (Рыба) , 68 34 байта

ri&:o&:&=\
l&io& /!?/
?!;20.\l!\

Вы можете запустить его на http://fishlanguage.com/playground вводя строку в качестве начального стека (с «отметками, т.е.« хамелеон ») и массивом дополнительных букв в качестве входного стека (без« отметок », то есть caln).

Не забудьте нажать кнопку Give, чтобы заполнить входной стек.

r       reverses the stack
i&      reads in the first input, and stores it in the register
:o      copies the top of the stack, and outputs the top of the stack
&:&     puts register value on stack, copies it, then puts top stack into register
=       checks if the top two values are equal, if yes push 1, else push 0
?       if top value is non-zero, execute next instruction
!       skips the following instruction (unless it was skipped by the previous ?)

If yes, then we proceed on the same line
&o      puts register value on stack, and outputs it
i&      reads in the first input, and stores it in the register
l       puts length of stack on stack, then proceed to lowest line

If no, we go directly to the last line
l       As above.
?!;     If zero value (from length), then end execution
20.     Push 2 and 0 onto stack, then pop top two values, and go to that position (2,0) (i.e. next instruction is at (3,0))

РЕДАКТИРОВАТЬ: вдвое! :)

Fongoid
источник
2

R 119

Исходя из ответа @ Алекса , этот на пару байтов короче:

function(s,a){message(unlist(lapply(strsplit(s,"")[[1]],function(x){if(length(a)&x==a[1]){a<<-a[-1];c(x,x)}else x})))}

Ungolfed:

function(s, a) {
  message(                             # Prints to output
    unlist(                            # Flattens list to vector
      lapply(                          # R's version of map
        strsplit(s,"")[[1]],           # Split vector to characters
        function (x) {
          if (length(a) & x == a[1]) { # If there are still elements in a
                                       # and there's a match
            a <<- a[-1]                # Modify a
            c(x, x)                    # And return the repeated character
          } else x                     # Otherwise just return it
        }
      )
    )
  )
}
JJA
источник
2

Perl, 73 62 59 56

Абсолютно новый подход дает гораздо лучшие результаты. Тем не менее, я уверен, что это может быть короче.

Звоните как f('coconut', ['c','o']).

sub f{($s,$a)=@_;$s=~s/(.*?)($_)/\U$1$2$2/ for@$a;lc$s}

Для каждого символа в массиве найдите первое вхождение, продублируйте его и переведите все в верхний регистр. Затем верните всю строку, преобразованную в нижний регистр.

РЕДАКТИРОВАТЬ: побрил еще пару персонажей, избавившись от shiftи pop.


Предыдущая версия:

sub f{join '',map{shift @{$_[0]}if s/($_[0][0])/$1$1/;$_}split //,shift}
JJA
источник
Новая версия больше не уважает порядок символов. (Кстати, « foreachКлючевое слово на самом деле является синонимом для forключевого слова, поэтому вы можете использовать любое из них». - Циклы Foreach .)
manatwork
@manatwork Это должно сделать это. И спасибо за forподсказку. Это на самом деле короче сейчас.
JJA
2

Рубин, 52 47 байт

Решение:

f=->(s,a){s.chars.map{|c|c==a[0]?a.shift*2:c}.join}

Пример:

p f.call('banana', ['n','a']) # => "bannaana"

Объяснение:

Proc форма метода, который принимает строку в качестве первого аргумента и массив символов в качестве второго аргумента. Сопоставляет блок с массивом символов в строковом аргументе, который проверяет каждый символ по первому элементу массива сравнения и, если есть совпадение, удаляет первый элемент массива сравнения и удваивает его.


Обновить

f=->s,a{s.chars.map{|c|c==a[0]?a.shift*2:c}*''}

Брайан Дэвис
источник
Вы можете пропустить круглые скобки вокруг параметров s,a. И *''эквивалентно .join. Это 5 сохраненных байтов, но я все еще бью тебя на один (пока): D
daniero
2

Perl, 51 байт

$s=<>;$s=~s=^.*$_=$_=,$,.=$&for split"",<>;print$,;

Ввод осуществляется через STDIN. Первый ввод - начальное слово (например chameleon), второй ввод - буквы в виде одной строки (например caln).

Вышесказанное является просто обфусцированным (читай "красивее") способом сделать следующее:

$word = <>;
for $letter(split "", <>) {
   $word =~ s/^.*$letter/$letter/;
   $result .= $&;
}
print $result;

Проходя каждую букву, мы заменяем от начала слова до буквы в исходном слове только новую букву и добавляем совпадение (сохраненное в $&) к нашему результату. Поскольку совпадение включает в себя букву, а затем заменяется буквой, каждая буква заканчивается дважды.

Поскольку STDIN добавляет символ новой строки к обоим нашим входам, мы гарантированно фиксируем остатки полного слова в последнем совпадении, то есть символ новой строки.

Аллен Г
источник
2

REGXY, 24 байта

Использует REGXY , язык подстановки регулярных выражений. Предполагается, что входными данными являются начальное слово и массив, разделенные пробелом (например, «хамелеон калн»).

/(.)(.* )\1| /\1\1\2/
//

Программа работает путем сопоставления символа в первой строке с первым символом после пробела. Если это соответствует, символ повторяется в подстановке, и символ в массиве удаляется (ну, не добавляется обратно в строку). Обработка переходит ко второй строке, которая является просто указателем на первую строку, что приводит к повторению обработки по результату предыдущей замены. В конце концов, после пробела не будет символов, после чего вторая ветвь чередования будет совпадать, удаляя завершающий пробел из результата. Затем регулярное выражение не будет соответствовать, обработка завершена и результат будет возвращен.

Если это помогает, итеративные шаги выполнения следующие:

chameleon caln
cchameleon aln
cchaameleon ln
cchaameleonn n
cchaameleonn  (with trailing space)
cchaameleonn

Программа компилируется и выполняется правильно с помощью примера интерпретатора по ссылке выше, но решение, возможно, немного дерзкое, поскольку оно основано на допущении в неопределенности языковой спецификации. Спецификация утверждает, что первый токен в каждой строке (перед /) действует как метка, но предполагается, что нулевой указатель метки будет указывать на первую команду в файле с нулевой меткой (или другими словами, это 'null' является допустимой меткой). Менее нахальное решение было бы:

a/(.)(.* )\1| /\1\1\2/
b//a

Что составляет 27 байтов

Jarmex
источник
1

JavaScript ES6, 72 байта

(s,a,i=0,b=[...s])=>a.map(l=>b.splice(i=b.indexOf(l,i+2),0,l))&&b.join``

Это анонимная функция, которая принимает 2 параметра: начальное слово в виде строки и символы для растяжения в виде массива. Разгруженный код, который использует ES5 и тестовый интерфейс ниже.

f=function(s,a){
  i=0
  b=s.split('')
  a.map(function(l){
    i=b.indexOf(l,i+2)
    b.splice(i,0,l)
  })
  return b.join('')
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('s').value,document.getElementById('a').value.split(''))};document.getElementById('run').onclick=run;run()
<label>Starting word: <input type="text" id="s" value="onomatopoeia" /></label><br />
<label>Leters to duplicate: <input type="text" id="a" value="oao"/></label><br />
<button id="run">Run</button><br />Output: <output id="output"></output>

NinjaBearMonkey
источник
1

Python 2, 77

def f(x,y,b=''):
 for i in x:
    try:
     if i==y[0]:i=y.pop(0)*2
    except:0
    b+=i
 print b

Звоните как:

f('onomatopoeia',['o','a','o'])

Возможно, я неправильно подсчитал количество байтов ... Использует смесь пробелов и табуляции.

Бета распад
источник
1

RS, 39 байт

Больше информации о rs.

Уже есть ответ Retina, но я думаю, что этот использует немного другой подход. Они также были созданы отдельно: когда я начал работать над этим, этот ответ не был опубликован.

Кроме того, этот в любом случае на 6 байт длиннее. :)

#
+#(\S)(\S*) ((\1)|(\S))/\1\4#\2 \5
#/

Живая демо-версия и тестовый набор.

kirbyfan64sos
источник
Мне очень нравится этот переключатель отладки в вашем интерпретаторе.
Деннис
@ Деннис Спасибо!
kirbyfan64sos
1

JavaScript, 92 символа

function f(s,c){r="";for(i=0;i<s.length;i++){r+=s[i];if(c.indexOf(s[i])>-1)r+=s[i]}return r}

Необъясненная версия:

function stretch(str, chars) {
    var ret = "";
    for(var i = 0; i < str.length; i++) {
        ret += str[i];
        if(chars.indexOf(str[i]) > -1) {
            ret += str[i];
        }
    }
    return ret;
}
SirPython
источник
1

R 136 128 122 байтов

function(s,a){p=strsplit(s,"")[[1]];for(i in 1:nchar(s))if(length(a)&&(x=p[i])==a[1]){p[i]=paste0(x,x);a=a[-1]};message(p)}

Это создает безымянную функцию, которая принимает строку и символьный вектор в качестве входных данных и печатает строку в STDOUT. Чтобы назвать это, дать ему имя.

Ungolfed + объяснение:

f <- function(s, a) {
    # Split s into letters
    p <- strsplit(s, "")[[1]]

    # Loop over the letters of s
    for (i in 1:nchar(s)) {

        # If a isn't empty and the current letter is the first in a
        if (length(a) > 0 && p[i] == a[1]) {

            # Replace the letter with itself duplicated
            p[i] <- paste0(p[i], p[i])

            # Remove the first element from a
            a <- a[-1]
        }
    }

    # Combine p back into a string and print it
    message(p)
}

Примеры:

> f("coconut", c("c","o"))
ccooconut

> f("onomatopoeia", c("o","a","o"))
oonomaatoopoeia

Благодаря MickeyT сэкономлено 8 байт, а jja - еще 3!

Алекс А.
источник
Вы можете использовать cat(p,sep='')для вывода прямо на STDOUT для пары
MickyT
@MickyT: не думал об этом! Спасибо, отредактировал. :)
Алекс А.
1
На самом деле, message(p)короче.
Джа
@jja: Я не знал о message, это круто! Благодарность! Отредактировано, чтобы использовать ваше предложение.
Алекс А.
1

Баш + Сед, 51

sed "`sed 's/./s!^[^&]*&!\U\&&!;/g'<<<$1`s/.*/\L&/"

Ввод от stdin; символы, которые должны быть удвоены как один аргумент:

$ echo chameleon | strtech caln
cchaamelleonn

Это работает путем построения программы sed из $2и затем выполнения ее против$1 . Программа sed заменяет первое вхождение каждой буквы замены двумя копиями ее заглавной версии, а в конце преуменьшает значение всей партии. Для приведенного выше примера сгенерированная программа sed

s!^[^c]*c!\U&C!;s!^[^a]*a!\U&A!;s!^[^l]*l!\U&L!;s!^[^n]*n!\U&N!;s/.*/\L&/

довольно отпечатанный:

# if only sed had non-greedy matching...
s!^[^c]*c!\U&C!
s!^[^a]*a!\U&A!
s!^[^l]*l!\U&L!
s!^[^n]*n!\U&N!
s/.*/\L&/

Я использую прописные буквы, чтобы отметить символы, обработанные до сих пор; это позволяет избежать повторного удвоения символов, которые уже были удвоены, или применения удвоения раньше, чем предыдущий.

Более ранняя версия, перед уточнением, что порядок замены списка является значительным (44 символа):

sed "`sed 's/./s!&!\U&&!;/g'<<<$1`s/.*/\L&/"
Тоби Спейт
источник
Неправильно. strtech na <<< bananaвыводит «baannana», но сначала вхождение на «n» должно быть удвоено, только после этого вхождение «a».
manatwork
В этом случае я неправильно понял вопрос; не было ясно, что порядок означал, что предыдущие буквы не должны быть удвоены, просто вы сможете найти последующую, чтобы удвоить. Я подумаю об альтернативе, которая удовлетворяет этому новому требованию.
Тоби Спейт
Нет проблем, я тоже не понял это с первого раза. Я предлагаю удалить ваш ответ, размышляя (вы можете отменить удаление в любое время позже), чтобы избежать шансов получить отрицательный отзыв.
manatwork
@manatwork: я попросил спрашивающего дать разъяснения и дал альтернативный ответ, который удовлетворяет этому чтению правил (но это стоило мне 7 символов)
Тоби Спейт
0

Python, 53 92 байта

Нашел мое решение одинаковой длины в Python 2 и 3.

РЕДАКТИРОВАТЬ: Человек, исправление этого случая, когда выполнение нескольких замен одной и той же буквы (при этом все еще используя тот же метод) потребовалось немного работы.

Python 2:

Попробуй здесь

def f(s,t):
 for c in t:s=s.replace(c,'%',1)
 print s.replace('%','%s')%tuple(x*2for x in t)

Python 3:

s,*t=input()
for c in t:s=s.replace(c,'%',1)
print(s.replace('%','%s')%tuple(x*2for x in t))
mbomb007
источник
0

Mathematica, 66 байт

""<>Fold[Most@#~Join~StringSplit[Last@#,#2->#2<>#2,2]&,{"",#},#2]&

Пример:

In[1]:= f = ""<>Fold[Most@#~Join~StringSplit[Last@#,#2->#2<>#2,2]&,{"",#},#2]&

In[2]:= f["banana", {"n", "a"}]

Out[2]= "bannaana"
alephalpha
источник
0

Луа, 76 78 76 75 58 53 байта

Новое, полностью переработанное решение с помощью wieselkatze и SquidDev! давай, ребята, мы можем победить мозговой трах: P

function f(a,b)print((a:gsub("["..b.."]","%1%1")))end

Объяснение грядущего завтра. Попробуй это здесь.


Оригинальное решение: экономия 2 байта благодаря @ kirbyfan64sos!

Lua - довольно ужасный язык для игры в гольф, так что, думаю, я неплохо справился с этим.

function f(x,y)for i=1,#x do g=y:sub(i,i)x=x:gsub(g,g..g,1)end print(x)end

Объяснение кода вместе с негольфированной версией:

function f(x,y) --Define a function that takes the arguements x and y (x is the string to stretch, y is how to stretch it)
  for i=1,#x do --A basic for loop going up to the length of x
    g=y:sub(i,i) -- Define g as y's "i"th letter
    x=x:gsub(g,g..g,1) --Redefine x as x with all letter "g"s having an appended g after them, with a replace limit of 1.
  end
  print(x)
end

Попробуй это здесь. (Устаревший код, но та же концепция, чуть менее удачная, обновит завтра)


источник
Добавлен на два байта, потому что мне пришлось исправить ошибку, где он заменит все буквы, определенные в массиве, с их дубликатами.
Я думаю, что вы можете удалить переводы строки после function f(x,y)и после print(x), сэкономив вам два байта.
kirbyfan64sos