Given a string s and a positive integer N, gradually duplicate each character more and more until N duplicates, and then staying at N duplicates until N characters away from the end, then step down again.

For example, given abalone and 3:

a    we start with 1 copy
bb   then 2 copies
aaa  then 3 copies, which is our second parameter
lll  so we continue using 3 copies
ooo  until we reach the end
nn   where we use 2 copies
e    and then finally 1 copy


and the result would be abbaaalllooonne.

It is guaranteed that the string has length greater than 2N and only has characters from a to z.

More testcases:

N string       output
2 aaaaa        aaaaaaaa
3 abcdabcdabcd abbcccdddaaabbbcccdddaaabbbccd


This is . Shortest answer in bytes wins. Standard loopholes apply.

# Jelly, 6 bytes

JṡFṢị⁸


Try it online!

### How it works

JṡFṢị⁸  Main link. Arguments: s (string), n (integer)

J       Get the indices of s.
ṡ      Split the indices into overlapping chunks of length n.
F     Flatten the array of chunks.
Ṣ    Sort the resulting array of indices.
ị⁸   Get the characters of s at these indices.


### Sample run

JṡFṢị⁸  "abalone", 3

J       [1, 2, 3, 4, 5, 6, 7].
ṡ      [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]]
F     [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7]
Ṣ    [1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7]
ị⁸  "abbaaalllooonne"

• That split+flatten+sort method is pure genius. Nice! :) Jul 4 '17 at 19:04

# Python 2, 57 bytes

f=lambda s,n,i=1:s and s[0]*len(s[:i][:n])+f(s[1:],n,i+1)


Try it online!

Also 57:

Python 2, 57 bytes

f=lambda s,n,i=1:s and s[0]*len(s[:i])+f(s[1:],n,i+(i<n))


Try it online!

• Can you explain your logic behind len(s[:i][:n])? I'm convinced there's a shorter way to get that number but I'm not sure how. Jul 4 '17 at 6:49
• Never mind, I got it! But it's one byte shorter than min(len(s),i,n). Great job! Jul 4 '17 at 6:53

# JavaScript (ES6), 67 65 bytes

-2 bytes thanks to Chas Brown's shorter method using min().

s=>n=>s.replace(/./g,(c,i)=>c.repeat(Math.min(i+1,s.length-i,n)))


Takes input in currying syntax: f("abalone")(3).

## Test Snippet

f=
s=>n=>s.replace(/./g,(c,i)=>c.repeat(Math.min(i+1,s.length-i,n)))
<div oninput="O.value=f(S.value)(+N.value)">String: <input id=S> N: <input id=N size=3></div>Out: <input id=O size=50 disabled>

# Jelly, 8 7 bytes

J««U$⁸x  Try it online! How it Works J««U$⁸x - main link, input e.g. abalone
J        - range of length of letters: [1,2,3,4,5,6,7]
«       - minimum of each term with second input: [1,2,3,3,3,3,3]
«U$- termwise minimum with the reverse: min([1,2,3,3,3,3,3],[3,3,3,3,3,2,1])=[1,2,3,3,3,2,1] ⁸x - repeat each character of the input a number of times corresponding to elements: a*1;b*2;a*3...e*1 = abbaaalllooonne  -1 byte thanks to @LeakyNun • Good find @LeakyNun! The closest I got in that direction was J«¥@«U$x@ for 9 bytes. Jul 4 '17 at 5:18
• Explanation please? Jul 4 '17 at 5:20
• @fireflame241 genenrally, x@⁸ is equivallent to ⁸x (I used ⁸ here) Jul 4 '17 at 5:38

Thanks to @Laikoni for helping to shave off 1 byte

n#s=do(i,c)<-zip[1..]s;replicate(minimum[n,i,length s-i+1])c


Try it online!

Ungolfed:

(#) n string = do
(i, char) <- zip [1..] string
replicate (minimum [n, i, length(string)-i+1]) char

• Great use of a do block! Save a byte by dropping the parenthesis in length(s). Jul 5 '17 at 5:28

r=replicate
f x n=join$zipWith r([1..n]++r(length x-2*n)n++reverse[1..n])x  Try it online! • Imports count in the score! You would be better of with >>=id Jul 4 '17 at 6:57 • Yeah, I did that too before and then I saw this (that's why there's Lambdabot in brackets). What is the right way? Jul 4 '17 at 7:54 • I stand corrected, I think this is alright! Jul 4 '17 at 8:01 • Good to know, there are a lot of very handy imports in that list. Jul 4 '17 at 8:03 # J, 24 bytes (<.&n<./(|.,:[)>:i.#s)#s  The bit in parens -- (<.&n<./(|.,:[)>:i.#s) -- creates the 1 2 ... n n n ... 2 1 array, as follows:  #s length of s, call it L i. numbers 0 1 ... L-1 >: increment by 1, now 1 2 ... L (|.,:[) fork: |. = reverse, ,: = stack, [ = identity resulting in L ... 2 1 1 2 ... L <./ min of each element of the top and bottom row <.&n min of each resulting elm and n  once we have that, J's # operator automatically does exactly what asked for, duplicating each element the number of times specified. Curious to see a J expert's improvment on this... • 23 bytes with a quite different approach [#~#@[$([:>:<:,&:i.-)@] (maybe a stray space got caught in there). I'm at a loss as to why the hook isn't taking x but not in too much a position to care.
– cole
Sep 5 '17 at 0:36

for([,$a,$n]=$argv;--$z?:($x=$a[$i]).$z=min($n,strlen($a)-$i,++$i);)echo$x;  PHP Sandbox Online # PHP>=7.1, 78 bytes for([,$a,$n]=$argv;~$x=$a[$i];)for($z=min($n,strlen($a)-$i,++$i);$z--;)echo$x;


PHP Sandbox Online

# PHP>=7.1, 80 bytes

for([,$a,$n]=$argv;$i<$l=strlen($a);)echo str_repeat($a[$i],min($n,$l-$i,++$i));


PHP Sandbox Online

# Japt, 11 10 bytes

ËpVm°TEnUÊ


Test it

## Explanation

Implicit input of string U and integer V.

Ë


Map over U and replace every character.

Vm


Get the minimum of V, ...

°T


T (initially 0) incremented by 1, ...

EnUÊ


And the index of the current character (E) subtracted from (n) the length (Ê) of U.

p


Repeat the current character that many times.

Implicitly output the final string.

# R, 87 bytes

function(N,s)paste(rep(strsplit(s,"")[[1]],c(1:N,rep(N,nchar(s)-2*N),N:1)),collapse="")


Try it online!

# Python 2 68 bytes

f=lambda s,n:''.join(s[i]*min(i+1,len(s)-i,n)for i in range(len(s)))

• You don't need the f= in the answer; the function can be anonymous. With that in mind, you can remove 3 bytes with lambda s,n:''.join(c*min(i+1,len(s)-i,n)for i,c in enumerate(s)). Jul 4 '17 at 4:44

# Husk, 10 9 bytes

₁₁ṀR
↔z↑N


Try it online!

The first line is the main function, it repeats each letter n times and then calls the second line twice.

The second line takes at most N letters from each group of repeated letters, where N is the 1-based index of the group, then reverses the list.

g 1
g _""_=""
g i(a:b)n=(a<$[1..min(length b+1)$min i n])++g(i+1)b n


Try it online!

# APL (Dyalog), 15 bytes

{⍵/⍨⍺⌊i⌊⌽i←⍳≢⍵}


{} function where left argument (cap) is and right argument (string) is :

≢⍵ count the number of characters in the string

⍳ generate that many ɩntegers

i← store in i

⌽ reverse

i⌊ pairwise minimum with i

⍺⌊ pairwise minimum with the cap

⍵/⍨ use those numbers to replicate the letters of the string

Try it online!

# F#, 96 bytes

let f(s:string)n=Seq.mapi(fun i c->System.String(c,Seq.min[i+1;s.Length-i;n]))s|>String.concat""


Try it online!

A port of Justin Mariners javascript answer

# Java (OpenJDK 8), 101 97 bytes

n->s->{int i=0,j;for(char c:s)for(j=s.length-i++,j=j<i?j:i,j=j<n?j:n;j-->0;)System.out.print(c);}


Try it online!

So much playing with indices...

Abalone is a type of fish (well, a shellfish), therefore…

# ><>, 79 bytes

&i1\
0(?\:1+:&::&@)?$~i:@ &~}\&~1 0(?\:&::1+&@)?$~}}:
~r\
?!v>l?!;:o\$1-:@
~~<^


Try it online, or watch it at the fish playground!

Reads the string from STDIN, and assumes the number is already on the stack.

Explanation: The second, fourth and sixth lines are the main loops. The details are some ugly stack manipulation, but in broad strokes, first, the second line fills the stack alternating between a character of input and min(in), where n is the length cap and i is the index of the character in the input: for "abalone", 3, the stack looks like

"a", 1, "b", 2, "a", 3, "l", 3, "o", 3, "n", 3, "e", 3, -1=EOF, 3


Next, line 4 goes through the stack in the same way in reverse, to get the right hand end capped properly:

"a", 1, "b", 2, "a", 3, "l", 3, "o", 3, "n", 2, "e", 1, -1


Then the sixth line takes each character–number pair and prints the character as many times as the number.