12
\$\begingroup\$

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.

\$\endgroup\$

17 Answers 17

11
\$\begingroup\$

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"
\$\endgroup\$
  • 3
    \$\begingroup\$ That split+flatten+sort method is pure genius. Nice! :) \$\endgroup\$ – HyperNeutrino Jul 4 '17 at 19:04
7
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – musicman523 Jul 4 '17 at 6:49
  • \$\begingroup\$ Never mind, I got it! But it's one byte shorter than min(len(s),i,n). Great job! \$\endgroup\$ – musicman523 Jul 4 '17 at 6:53
6
\$\begingroup\$

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>

\$\endgroup\$
6
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Good find @LeakyNun! The closest I got in that direction was J«¥@«U$x@ for 9 bytes. \$\endgroup\$ – fireflame241 Jul 4 '17 at 5:18
  • \$\begingroup\$ Explanation please? \$\endgroup\$ – Comrade SparklePony Jul 4 '17 at 5:20
  • \$\begingroup\$ @fireflame241 genenrally, x@⁸ is equivallent to ⁸x (I used here) \$\endgroup\$ – Leaky Nun Jul 4 '17 at 5:38
2
\$\begingroup\$

Haskell, 61 60 bytes

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
\$\endgroup\$
  • \$\begingroup\$ Great use of a do block! Save a byte by dropping the parenthesis in length(s). \$\endgroup\$ – Laikoni Jul 5 '17 at 5:28
1
\$\begingroup\$

Haskell (Lambdabot), 74 bytes

r=replicate
f x n=join$zipWith r([1..n]++r(length x-2*n)n++reverse[1..n])x

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Imports count in the score! You would be better of with >>=id \$\endgroup\$ – bartavelle Jul 4 '17 at 6:57
  • \$\begingroup\$ Yeah, I did that too before and then I saw this (that's why there's Lambdabot in brackets). What is the right way? \$\endgroup\$ – ბიმო Jul 4 '17 at 7:54
  • \$\begingroup\$ I stand corrected, I think this is alright! \$\endgroup\$ – bartavelle Jul 4 '17 at 8:01
  • \$\begingroup\$ Good to know, there are a lot of very handy imports in that list. \$\endgroup\$ – ბიმო Jul 4 '17 at 8:03
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – cole Sep 5 '17 at 0:36
1
\$\begingroup\$

PHP>=7.1, 75 bytes

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

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

Python 2 68 bytes

f=lambda s,n:''.join(s[i]*min(i+1,len(s)-i,n)for i in range(len(s)))
\$\endgroup\$
  • \$\begingroup\$ 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)). \$\endgroup\$ – notjagan Jul 4 '17 at 4:44
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

Haskell, 68 bytes

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!

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.