Alongamento de palavras

32

Escreva um programa ou função que duplique letras em uma palavra, para que todas as letras duplicadas organizadas da esquerda para a direita na palavra formem a matriz de entrada.

Por exemplo:

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

Entrada

  • A palavra inicial (por exemplo chameleon)
  • Uma matriz de caracteres ( [c,a,l,n]) ou uma sequência para representar uma matriz ( caln) ou algo semelhante
  • A entrada pode ser feita através de parâmetros de função, STDIN ou equivalentes de idioma
  • Todas as entradas serão minúsculas (az)

Saída

  • A palavra mudada

  • Se houver várias soluções, qualquer uma pode ser impressa

    input: banana [n,a]  
    possible outputs: bannaana, banannaa
                         |-|---------|-|--->[n,a]
    
  • Você pode assumir que a palavra de entrada (não necessariamente a matriz) terá as letras na matriz (em ordem)

  • Você também pode assumir que as entradas não possuem letras consecutivas iguais (NÃO maçã, geek, verde, vidro, porta ...)

Exemplos

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.

O programa mais curto vence!

Classificação (obrigado a Martin Büttner pelo trecho)

Stretch Maniac
fonte
@AlexA. apenas uma instância porque, caso contrário, a matriz formada pelas letras duplicadas seria [c,o,c,o], e não [c,o].
Stretch Maniac
Sim, desculpe, lendo novamente, isso é óbvio. Obrigado.
Alex A.
2
Vendo isso, recebemos muitas respostas, e muitas nos mesmos idiomas, você estaria interessado em adicionar o snippet da tabela de classificação ? Nesse caso, fico feliz em editá-lo e emendar as respostas que não usam o formato de cabeçalho necessário.
Martin Ender
@ MartinBüttner Eu esqueci disso! Adicionado. Eu tive que alterar #answer-liste #language-listlargura 50%para evitar a sobreposição de colunas no seu snippet.
Stretch Maniac
11
Esclarecimento (veja minha bash+ sedresposta): É ilegal para banana, na=> baannana? Eu acreditava que "Você pode assumir que todas as entradas terão as letras na matriz (em ordem)" deve permitir , mas não exigir , respostas para processar as duas listas sequencialmente, mas o @manatwork a interpretou de maneira diferente.
Toby Speight

Respostas:

5

Pitão, 14 bytes

s+L&@d<Q1.(QZz

Demonstração.

Estilo de entrada:

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

Explicação:

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
fonte
43

Brainfuck, 46 45 (63 com caracteres imprimíveis na entrada)

Compatível com Alex Pankratov bff (intérprete brainfuck usado em SPOJ e ideone) e de Thomas Cort BFI (usado em Anarchy Golf).

A versão imprimível leva a matriz primeiro como uma sequência, seguida por uma guia, seguida pela sequência inicial sem uma nova linha à direita.

Demonstração em ideone.

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

Podemos salvar alguns bytes usando \x00como separador em vez de tab:

,[>,]
<[<]
<,+
[
  -.
  [>+>-<<-]
  >>
  [
    <[>+<-]
  ]
  <[.[-]]
  ,+
]
Mitch Schwartz
fonte
22
Esse sentimento quando BF é mais curto do que o meu código Python .. :(
Kade
6
Eu geralmente não ligo para Brainfuck, mas isso é incrível!
Dennis
Isso é lindo.
21715 Joshpbarron
14

CJam, 15 bytes

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

Experimente online.

Como funciona

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).
Dennis
fonte
É uma batalha dos CJams! Você e Sp têm respostas CJam de 15 bytes e 15 é atualmente o mais curto. :)
Alex A.
3
@AlexA. Just wait for Pyth. You just wait...
Sp3000
2
Sounds like you'd better learn Pyth. ;)
Alex A.
12

C, 62 bytes

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

Well, this is surprisingly competetive.

We define a function f(char*, char*) that takes the string as its first input and the array of characters to duplicate as its second input.

Some testing code:

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

Which prints:

oonomaatoopeia

Try it online!

If it is acceptable to submit a macro rather than a function, the following #define g(s,c) is just 58 bytes, but requires s and c to be actual pointers:

#define g(s,c)while(*s-*c||putchar(*c++),*s)putchar(*s++);
BrainSteel
fonte
1
Thanks for making me look up the comma operator. That's useful!
Oliphaunt - reinstate Monica
11

CJam, 15 bytes

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

An alternative CJam approach. Try it online

Explanation

For each character in the second string, we do two things.

  1. Split the current suffix of the string by the character, e.g. "beeper" "e" -> ["b" "" "p" "r"]

  2. Uncons the first string in the array, insert two of the character, then rejoin the rest of the array with the character, e.g. "b" "ee" "eper". The last string is the new suffix.

Sp3000
fonte
9

Retina, 33 bytes

More information about Retina.

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

This expects the two strings on STDIN, separated by a newline.

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
fonte
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
fonte
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
fonte
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
fonte
"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
fonte
2
If VBA isn't indentation-sensitive, you could get rid of all of the indents and save a few bytes. I think you can also get rid of all of the spaces after commas and around operators. Ought to save you a few bytes.
Fund Monica's Lawsuit
@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
fonte
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
fonte
4

Javascript, 47 bytes

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

Taking advantage of some ES6 features.

Cereal
fonte
1
Does this work correctly for onomatopoeia, oao?
Alex A.
1
@AlexA. Outputs: "oonoomaatoopooeiaa". Ah, I understand. Will fix
Cereal
Fixed, I think. Added a lot of characters :(
Cereal
Instead of b.indexOf(d)==0, try ~b.search(d)
Ismael Miguel
@IsmaelMiguel search is only applicable on strings. Had to change b to an array
Cereal
3

Pyth, 16 bytes

u|pH<GJxGH>GJwz

Try it online: Demonstration

This is quite hacky. Stack-based languages might have an advantage here.

Explanation

                   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
fonte
@isaacg Help? There must be something shorter...
Jakube
And more elegant ;-)
Jakube
1
Got it in 14 - 1 less than CJam is the best place to be.
isaacg
3

JavaScript ES6, 47 bytes

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

Assumes s is an array ["c","a","l","n"]

Shmiddty
fonte
2

><> (Fish), 68 34 Bytes

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

You can run it at http://fishlanguage.com/playground inputting the string as the initial stack (with " marks, i.e. "chameleon") and the array of extra letters as the input stack (no " marks i.e. caln).

Don't forget to press the Give button to seed the input stack.

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

EDIT: Halved it! :)

Fongoid
fonte
2

R, 119

Based on @Alex's answer, this one is a couple of bytes shorter:

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
fonte
2

Perl, 73 62 59 56

Entirely new approach yields much better results. Still, I bet it can be shorter.

Call as f('coconut', ['c','o']).

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

For each character in the array, find the first occurrence and duplicate it, and turn everything up to it to uppercase. Then return the entire string, converted to lowercase.

EDIT: shaved a couple of more characters by getting rid of shift and pop.


The previous version:

sub f{join '',map{shift @{$_[0]}if s/($_[0][0])/$1$1/;$_}split //,shift}
jja
fonte
The new version doesn't respect the character order anymore. (BTW, “The foreach keyword is actually a synonym for the for keyword, so you can use either.” – Foreach Loops.)
manatwork
@manatwork That should do it. And thanks for the for hint. It's actually shorter now.
jja
2

Ruby, 52 47 bytes

Solution:

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

Example:

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

Explanation:

Proc form of a method which takes a string as the first argument, and an array of characters as the second argument. Maps a block onto an array of the characters in the string argument, which checks each character against first element of the comparison array, and if there is a match, removes the first element of the comparison array, and doubles it.


update

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

Brian Davis
fonte
You can skip the parentheses around the parameters s,a. And *'' is equivalent to .join. That's 5 bytes saved, but I still beat you by one (for now) :D
daniero
2

Perl, 51 bytes

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

Input is provided via STDIN. First input is the starting word (e.g. chameleon), second input is the letters as a single string (e.g. caln).

The above is just an obfuscated (read "prettier") way of doing the following:

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

As we go through each letter, we replace from the start of the word up to the letter in the source word with just the new letter, and append the match (stored in $&) to our result. Since the match includes the letter and then gets replaced with the letter, each letter ends up appearing twice.

Because STDIN appends a new line character to both of our inputs, we're guaranteed to capture the remnants of the full word on the last match, i.e. the new line character.

Allen G
fonte
2

REGXY, 24 bytes

Uses REGXY, a regex substitution based language. Input is assumed to be the starting word and the array, space separated (e.g. "chameleon caln").

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

The program works by matching a character in the first string with the first character after a space. If this matches, the character is repeated in the substitution and the character in the array is removed (well, not appended back into the string). Processing moves on to the second line, which is just a pointer back to the first line, which causes processing to repeat on the result of the previous substitution. Eventually, there will be no characters after the space, at which point the second branch of the alternation will match, removing the trailing space from the result. The regex will then fail to match, processing is completed and the result is returned.

If it helps, the iterative steps of execution are as follows:

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

The program compiles and executes correctly with the sample interpreter in the link above, but the solution is perhaps a bit cheeky as it relies on an assumption in the vagueness of the language specification. The spec states that the first token on each line (before the /) acts as a label, but the assumption is that a null label-pointer will point back to the first command in the file with a null label (or in other words, that 'null' is a valid label). A less cheeky solution would be:

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

Which amounts to 27 bytes

Jarmex
fonte
1

JavaScript ES6, 72 bytes

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

This is an anonymous function that takes 2 parameters: the starting word as a string and the characters to stretch as an array. Ungolfed code that uses ES5 and test UI below.

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
fonte
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

Call as:

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

I may have got the byte count horribly wrong... Uses a mixture of spaces and tabs.

Beta Decay
fonte
1

rs, 39 bytes

More information about rs.

There's already a Retina answer, but I think this one uses a slightly different approach. They were also created separately: when I began working on this one, that answer hadn't been posted.

Besides, this one is 6 bytes longer anyway. :)

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

Live demo and test suite.

kirbyfan64sos
fonte
I really like that debug switch in your interpreter.
Dennis
@Dennis Thanks!
kirbyfan64sos
1

JavaScript, 92 characters

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}

Unobfuscated version:

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
fonte
1

R, 136 128 122 bytes

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

This creates an unnamed function that accepts a string and a character vector as input and prints a string to STDOUT. To call it, give it a name.

Ungolfed + explanation:

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

Examples:

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

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

Saved 8 bytes thanks to MickeyT and another 3 thanks to jja!

Alex A.
fonte
You could use cat(p,sep='') to output straight to STDOUT for a couple
MickyT
@MickyT: Didn't think of that! Thanks, edited. :)
Alex A.
1
Actually, message(p) is shorter.
jja
@jja: I didn't know about message, that's awesome! Thanks! Edited to use your suggestion.
Alex A.
1

Bash+sed, 51

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

Input from stdin; characters to be doubled as a single argument:

$ echo chameleon | strtech caln
cchaamelleonn

This works by constructing a sed program from $2 and then executing it against $1. The sed program replaces the first occurrence of each replacement letter with two copies of its uppercase version, and downcases the whole lot at the end. For the example above, the generated sed program is

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

pretty-printed:

# 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&/

I use the uppercase to mark characters processed so far; this avoids re-doubling characters that have already been doubled, or applying a doubling earlier than the previous one.

Earlier version, before clarification that order of replacement list is significant (44 chars):

sed "`sed 's/./s!&!\U&&!;/g'<<<$1`s/.*/\L&/"
Toby Speight
fonte
Incorrect. strtech na <<< banana outputs “baannana”, but first an occurrence on “n” should be doubled, only after that an occurrence of “a”.
manatwork
In that case, I've misunderstood the question; it wasn't explicit that the ordering meant that prior letters should not be doubled, simply that you would be able to find a subsequent one to double. I'll have a think about an alternative that satisfies this new requirement.
Toby Speight
No problem, neither I got it right the first time. I suggest to delete your answer while thinking (you can undelete any time later), to avoid the chance to get downvoted.
manatwork
@manatwork: I've asked the questioner for clarification, and provided an alternative answer that satisfies that reading of the rules (but it cost me 7 chars to do so)
Toby Speight
0

Python, 53 92 bytes

Found my solution to be the same length in both Python 2 and 3.

EDIT: Man, fixing that case when doing multiple replaces of the same letter (while still using the same method) took a bit of work.

Python 2:

Try it here

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
fonte
0

Mathematica, 66 bytes

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

Example:

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

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

Out[2]= "bannaana"
alephalpha
fonte
0

Lua, 76 78 76 75 58 53 bytes

New, completely reworked solution with help from wieselkatze and SquidDev! come on guys, we can beat brainfuck :P

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

Explanation coming tommorow. Try it here.


Original solution: Saved 2 bytes thanks to @kirbyfan64sos!

Lua is a pretty terrible language to golf in, so I think I did pretty good for this one.

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

Code explanation, along with ungolfed version:

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

Try it here. (Outdated code but same concept, just less golfed, will update tommorow)


fonte
Added on two bytes because I had to fix glitch where it would replace all letter defined in the array with their duplicates.
I think you can remove the newlines after function f(x,y) and after print(x), saving you two bytes.
kirbyfan64sos