# Stretching Words

Write a program or function that duplicates letters in a word, so that all the duplicated letters arranged from left to right in the word would form the input array.

For example:

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


## Input

• The starting word (e.g. chameleon)
• An array of characters ([c,a,l,n]) or a string to represent an array (caln), or something similar
• Input can be through function parameters, STDIN or language equivalents
• All inputs will be lower-case letters (a-z)

## Output

• The changed word

• If there are multiple solutions, any can be printed

input: banana [n,a]
possible outputs: bannaana, banannaa
|-|---------|-|--->[n,a]

• You may assume that the input word (not necessarily the array) will have the letters in the array (in order)

• You may also assume that the inputs have no consecutive letters which are the same (NOT apple, geek, green, glass, door...)

## Examples

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.


Shortest program wins!

Leaderboard (thanks to Martin Büttner for the snippet)

/* Configuration */

var QUESTION_ID = 51984; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page

/* App */

var answers = [], page = 1;

return "http://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
else process();
}
});
}

var SIZE_REG = /\d+(?=[^\d&]*(?:&lt;(?:s&gt;[^&]*&lt;\/s&gt;|[^&]+&gt;)[^\d&]*)*)/; var NUMBER_REG = /\d+/; var LANGUAGE_REG = /^#*\s*([^,]+)/; function shouldHaveHeading(a) { var pass = false; var lines = a.body_markdown.split("\n"); try { pass |= /^#/.test(a.body_markdown); pass |= ["-", "="] .indexOf(lines[1][0]) > -1; pass &= LANGUAGE_REG.test(a.body_markdown); } catch (ex) {} return pass; } function shouldHaveScore(a) { var pass = false; try { pass |= SIZE_REG.test(a.body_markdown.split("\n")[0]); } catch (ex) {} return pass; } function getAuthorName(a) { return a.owner.display_name; } function process() { answers = answers.filter(shouldHaveScore) .filter(shouldHaveHeading); answers.sort(function (a, b) { var aB = +(a.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0], bB = +(b.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0]; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; answers.forEach(function (a) { var headline = a.body_markdown.split("\n")[0]; //console.log(a); var answer = jQuery("#answer-template").html(); var num = headline.match(NUMBER_REG)[0]; var size = (headline.match(SIZE_REG)||[0])[0]; var language = headline.match(LANGUAGE_REG)[1]; var user = getAuthorName(a); if (size != lastSize) lastPlace = place; lastSize = size; ++place; answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", user) .replace("{{LANGUAGE}}", language) .replace("{{SIZE}}", size) .replace("{{LINK}}", a.share_link); answer = jQuery(answer) jQuery("#answers").append(answer); languages[language] = languages[language] || {lang: language, user: user, size: size, link: a.share_link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang > b.lang) return 1; if (a.lang < b.lang) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } } body { text-align: left !important} #answer-list { padding: 10px; width: 50%; float: left; } #language-list { padding: 10px; width: 50%px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> • @AlexA. only one instance because otherwise the array formed by the duplicate letters would be [c,o,c,o], rather than [c,o]. Jun 22, 2015 at 16:03 • Yeah sorry, reading it again that's obvious. Thanks. Jun 22, 2015 at 16:08 • Seeing this got quite a lot of answers, and many in the same languages, would you be interested in adding the leaderboard snippet? If so, I'm happy to edit it in and amend the answers that don't use the required header format. Jun 23, 2015 at 13:12 • @MartinBüttner I forgot about that! Added. I had to change #answer-list and #language-list width to 50% to avoid overlapping columns in your snippet. Jun 23, 2015 at 20:49 • Clarification (see my bash+sed answer): Is it illegal for banana, na => baannana? I believed that "You may assume that all inputs will have the letters in the array (in order)" is meant to permit, but not require, answers to process both lists sequentially, but @manatwork interpreted it differently. Jun 24, 2015 at 12:48 ## 38 Answers # 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"  # Lua, 7678767558 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) • Added on two bytes because I had to fix glitch where it would replace all letter defined in the array with their duplicates. – user40734 Jun 22, 2015 at 19:27 • I think you can remove the newlines after function f(x,y) and after print(x), saving you two bytes. Jun 23, 2015 at 15:46 # Ruby, 46 bytes f=->s,a{a.map{|c|y,s=s.split(c,2);y+c*2}*''+s}  For each character c in the array a, divide the string s in two halves on the first occurrence of c. Add two copies of the c to the first half, and continue with the other half of s. Join it all together and add the remainder of s :) Examples: f["coconut", %w(c o)] => "ccooconut" f["banana", %w(b a a)] => "bbaanaana"  # C, 57 Inspired by BrainSteel's answer: f(char*s,char*c){while(*c-putchar(*s++)||putchar(*c++));}  This uses the result of putchar to determine whether we've hit one of the replacement list, and if so, advance one through the replacement list, outputting as we go. If we don't consume all the replacements, we'll go off the end of the input string, but luckily the rules guarantee we wont. :-) ### Test harness: int main(int argc, char* argv[]) { f(argv[1], argv[2]); return 0; }  • This code assumes no double letters in the replacement list. I don't think that's an assumption you are allowed to make, as the 4th test case has double letters. That is what drove me away from this approach :( Jun 24, 2015 at 16:56 • @BrainSteel - I've withdrawn the answer that makes the assumption "no double letters in the replacement list", and edited this to a new answer. I can no longer avoid 2xputchar, but I save a few chars by using their results. Jun 25, 2015 at 8:15 ## C#, 116 bytes Indented for clarity: string F(string s,string c){ int i; return c=="" ?s :s.Remove(i=s.IndexOf(c[0]))+c[0]+F(s.Substring(i),c.Substring(1)); }  # Perl 5-p, 29 bytes _=<>=~s/./$&.$&x s!^$&!!/ger  Try it online! # SM83/Z80 machine language, 14 bytes Takes input 1 in de, input 2 in hl, output to bc. 1A 13 02 03 B7 C8 BE 20 F7 02 03 23 18 F2  stretch: ld a,(de) // 1A load input 1 char inc de // 13 and increment ld (bc),a // 02 store it inc bc // 03 and increment or a // B7 test for 0 ret z // C8 return if so cp (hl) // BE test against input 2 char jr nz,stretch // 20 F7 if not same, continue ld (bc),a // 02 if same, store again inc bc // 03 and increment again inc hl // 23 also increment input 2 char jr stretch // 18 F2 loop back  The register pressure is extreme on this one. There's just enough room for three pointers and a character without pushing things to memory. It's impossible to do it this efficiently without putting the second input into hl. ## PHP, 145 Bytes  <?php$a=str_split($argv[1]);$b=str_split($argv[2]); foreach($a as $x){ if($x==$b[0]) {$w[] = $x .$x;
array_shift($b); } else$w[] = $x; } echo implode($w);


Definitely not the shortest answer, but no one else has done PHP yet so why not! Takes the word as the first argument, and a string representing the characters to be duplicated for the second argument.

I'm still new to golfing, so let me know if you see anything I could improve. Thanks!