Tower of strings

Tower of strings



Given a string of text, output it as a 'tower'.



Each slice of the string (of the form 0:n) is repeated 5*n times, so the first character is repeated 5 times, then the first and the second 10 times, etc.


0:n


5*n


'hello' ->

['h']
['h']
['h']
['h']
['h']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']
['h', 'e', 'l', 'l', 'o']


'cat' ->

['c']
['c']
['c']
['c']
['c']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']
['c', 'a', 't']



You can output each layer as a list of characters or just a string of them joined together.





welcome to PPCG! Nice challenge.
– Giuseppe
Aug 19 at 19:37





I tried to clean up the formatting and explain the challenge a little bit better. Did I understand the challenge right?
– Picard
Aug 19 at 19:39





Can we take the input as a list of characters ?
– JayCe
Aug 19 at 19:54





Can we output a 2D-array of strings like so: [["c","c","c","c","c"],["ca","ca","ca","ca","ca","ca","ca","ca","ca","ca"],...]?
– Shaggy
Aug 19 at 20:48


[["c","c","c","c","c"],["ca","ca","ca","ca","ca","ca","ca","ca","ca","ca"],...]





Are outputs with leading or trailing newlines acceptable? Can we assume inputs do not contain newlines?
– redundancy
Aug 20 at 0:12




34 Answers
34




R, 48 bytes


function(s)substring(s,1,rep(x<-1:nchar(s),x*5))



Try it online!



Returns a list of strings.





I had missed the obvious golf here! nice solution I tried different approaches but so far all are far longer than this.
– JayCe
Aug 19 at 20:21





@J.Doe that's a pretty sweet suggestion, but unfortunately you aren't allowed to hardcode input like that; using scan or similar would get to you to, I believe, 49 bytes
– Giuseppe
12 hours ago


scan





@J.Doe but I think you could modify it to return the list of strings rather than write, which you should post as your own answer, as it's shorter than mine! EDIT: ah, J.Doe deleted their previous comment, so now I don't know how to reach them
– Giuseppe
12 hours ago



write




Haskell, 36 bytes


f""=
f s=f(init s)++(s<$s<*[1..5])



Try it online!




05AB1E, 6 bytes


ηā5*ÅΓ



Try it online!



Returns a list of string.



Explanation


ÅΓ # Run-length decode...
η # ... the prefixes of the input
ā5*и # ... with the length range multiplied by 5 -- [5, 10, 15, 20, 25]





@KevinCruijssen Thanks for noticing that ! I should not golf in the morning without a coffee first :-(
– Kaldo
Aug 20 at 9:09





Using run length decoding saves 3 bytes: ηā5*ÅΓ
– Adnan
Aug 20 at 10:01


ηā5*ÅΓ





@Adnan Brilliant, thanks ! I think it deserves its own answer though, you've reduced the byte count by 33%... I'll revert to my original solution if you decide to post it yourself.
– Kaldo
Aug 20 at 12:06






Nice one, I had ηvyg5*Fy= for 8.
– Magic Octopus Urn
2 days ago



ηvyg5*Fy=




Stax, 8 bytes


äï▄;♫├W^



Run and debug it



Unpacked, ungolfed, and commented, it looks like this.


|[F for each prefix of the input
i^5* 5*(i+1) where i is the iteration index
DQ that many times, peek and print to output



Run this one



TI-Basic (TI-84 Plus CE), 29 bytes (27 tokens)


For(A,1,length(Ans
For(B,1,5A
Disp sub(Ans,1,A
End
End



Explanation:


For(A,1,length(Ans # 9 bytes, 8 tokens: for A from 1 to the length of the string
For(B,1,5A # 8 bytes, 8 tokens: 5*A times
Disp sub(Ans,1,A # 9 bytes, 8 tokens: Print the first A characters of the string
End # 2 bytes, 2 tokens: end loop
End # 1 byte, 1 token: end loop




Retina, 15 bytes


.
$.>`*5*$($>`¶



Try it online! Link includes test cases. Explanation:


.



Match each character in the string.


$.>`*5*$($>`¶



$` is the prefix of the match. Retina then provides two modifiers, > modifies it to be in the context of the string between successive matches, while . takes the length. We therefore start with the prefix of the suffix, which is equivalent to the match including its prefix. This saves 2 bytes over using overlapping matches. The $( then concatenates that with a newline, the 5* repeats it, and then the $.>` repeats it a further number of times given by its length.


$`


>


.


$(


5*


$.>`




Canvas, 6 bytes


[³5×*P



Try it here!



Explanation:


[ for each prefix
³5× 1-indexed counter * 5
* repeat the prefix vertically that many times
P and print that




Brachylog, 15 bytes


a₀ᶠ⟨gj₎l×₅⟩ᵐc



Try it online!



The final c can be removed if OP replies positively to the question about outputting 2D arrays.


c




Cubix,  44  40 bytes


i.!?@UBqwW_#/>u...;B^...?qo;;q*n5;oN/./)



Try it online!



This still has a lot of no-ops, but it is a little better than before.



As a very brief description, a character is grabbed from input and tested for EOI (-1), halt if it is. The stack is then reversed. Get the number of items on the stack and multiple by -5. Drop that to the bottom of the stack and clean up. Loop through the stack, printing, until a negative number. Print newline, increment the number, if 0 drop the zero, reverse stack and start from input again, otherwise loop through the stack, printing, until a negative number ... ad nauseum



Cubified it looks like


i . !
? @ U
B q w
W _ # / > u . . . ; B ^
. . . ? q o ; ; q * n 5
; o N / . / ) . . . . .
. . .
. . .
. . .



Watch it online




Jelly, 8 bytes


¹Ƥx'J×5Ɗ



Try it online!


J×5x'@¹Ƥ



Try it online!


¹Ƥx'Jx'5



Try it online!



This is likely golfable.





A slightly different 8 is +ẋ"Jx5Ẏ
– Jonathan Allan
Aug 20 at 0:05


+ẋ"Jx5Ẏ




Python 3, 43 41 bytes



Thanks to ovs for saving 2 bytes!


f=lambda x:[*x]and f(x[:-1])+[x]*5*len(x)



Try it online!



JavaScript, 48 46 bytes



(thanks @redundancy)



Edit: The author clarified and this answer is now not valid, but I will leave it here unchanged.



Returns an array of multi-line strings.


s=>[...s].map(c=>(q+=c).repeat(5*++i),i=q=`
`)



Try it




f = s=>[...s].map(c=>(q+=c).repeat(5*++i),i=q=`
`);

console.log( f("hello").join`` );



Potential strategy:



It didn't help me much, but maybe someone can use this:



The number of characters at (0-indexed) line i is floor(sqrt(2/5*i+1/4)+1/2), which is golfed in JavaScript as (.4*i+.25)**.5+.5|0.


i


floor(sqrt(2/5*i+1/4)+1/2)


(.4*i+.25)**.5+.5|0



For a string of length n, there are n*(n+1)*5/2 lines.


n


n*(n+1)*5/2



Perhaps:
s=>for(i=0;(n=(.4*i+++.25)**.5+.5


s=>for(i=0;(n=(.4*i+++.25)**.5+.5





Assuming your output format is valid according to the challenge, you can save 2 bytes as demonstrated here: Try it online!
– redundancy
Aug 20 at 0:39




C (gcc), 67 bytes


i,j;f(char*s)for(i=0;s[i++];)for(j=5*i;j--;)printf("%.*sn",i,s);



Try it online!




Husk, 8 bytes


ΣzoR*5Nḣ



Try it online!


Σz(R*5)Nḣ -- example input: "ab"
ḣ -- non-empty prefixes: ["a","ab"]
z( )N -- zip with [1..]
*5 -- | multiply by 5
R -- | replicate
-- : [["a","a","a","a","a"],["ab","ab","ab","ab","ab","ab","ab","ab","ab","ab"]]
Σ -- concat: ["a","a","a","a","a","ab","ab","ab","ab","ab","ab","ab","ab","ab","ab"]




Charcoal, 11 bytes


F⊕LθE×⁵ι…θι



Try it online! Link is to verbose version of code. Output includes 0 repetitions of the zero-length substring. Explanation:


θ Input string
L Length
⊕ Incremented
F Loop over implicit range
⁵ Literal 5
ι Current index
× Multiply
E Map over implicit range
θ Input string
ι Current index
… Chop to length
Implicitly print each string on its own line




MATL, 12 bytes


f"G@:)@5*1X"



Try it online!


f % Get the indices of input i.e. range 1 to length(input)
" % For loop over that
G % Push input string
@ % Push current loop index
: % Range 1 to that
) % Index at those positions (substring 1 to i)
@5* % Multiply loop index by 5
1X" % Repeat the substring that many times rowwise
% Results collect on the stack and are
% implicitly output at the end




V, 17 bytes


òïç$îî/6Ä
Hl$xòxú



Expects inputs without newlines, and outputs with superfluous leading newlines.



I can remove this entry if input/output violates the challenge spec.



Try it online!


òïç$îî/6Ä
Hl$xòxíîî/ò



Expects inputs without newlines, but outputs with only one leading and trailing newline.



Differing substrings are separated with two consecutive newlines so that
linewise duplication only applies to lines matching the regex $nn.


$nn



When the duplication command (Ä) is supplied a count, e.g. , (I think) it
deletes the current line before pasting n times, thus only appearing to append n - 1 copies.


Ä



n


n - 1


ò | recursively...
ï | . append newline
ç | . globally search lines matching...
$îî | . . compressed version of $nn regex
/6Ä | . . duplicate to create 6 copies
H | . go to first line
l | . move cursor right 1 char
| . . if current line is 1 char long, errors out of recursion
$x | . delete 1 char from end of current line
ò | ...end
x | delete extra 1-char substring
ú | sort so that newlines rise to top


f s=do n<-[1..length s];take n s<$[1..n*5]



Try it online!



Sadly inits requires import Data.List, so


inits


import Data.List


import Data.List
((<$)<*>(>>[1..5])=<<).inits



with its 45 bytes is longer.



Edit: -1 byte thanks to @BWO.


mapsay($x.=$_)x($y+=5)for@F



Try it online!




Perl 6, 25 bytes


(1..*X*5)RZxx[~] .comb



Try it online!



Anonymous code block that returns a list of list of strings.



If you want it as a 1D array, you can append flat in front like so:


flat


flat (1..*X*5)RZxx[~] .comb



Try it online!


# Anonymous code block
.comb # Split the string into a list of characters
[~] # Triangular reduce the list of characters with the concatenate operator
RZxx # Multiply each list by:
(1..*X*5) # A sequence of 5,10,15 etc.



Alternatively,


($+=5)xx*RZxx[~] .comb



Try it online!



Also works for the same amount of bytes.



Japt, 10 bytes



Awaiting confirmation as to whether the output format is acceptable (+2 bytes if not).


å+ £T±5 ÇX



Try it





Output looks reasonable to me, nicely done.
– Nit
Aug 20 at 10:10



Java 10, 120 92 90 bytes


s->for(int j=1,i=1;i<=s.length();i+=j++>=i*5?j=1:0)System.out.println(s.substring(0,i));



-28 bytes thanks to @OlivierGrégoire.



Try it online.



Explanation:


s-> // Method with String parameter and no return-type
for(int j=1, // Repeat-integer, starting at 1
i=1;i<=s.length() // Loop `i` in the range [1,length_input]
; // After every iteration:
i+=j++>=i*5? // If `j` is larger than or equal to `i` multiplied by 5:
// (and increase `j` by 1 afterwards with `j++`)
j=1 // Increase `i` by 1, and reset `j` to 1
: // Else:
0) // Leave `i` the same by increasing it with 0
System.out.println( // Print with trailing newline:
s.substring(0,i)); // The prefix of size `i`





92 bytes: s->for(int i=1,j=1;i<=s.length();i+=j++<i*5?0:+(j=1))System.out.println(s.substring(0,i));
– Olivier Grégoire
Aug 20 at 9:30



s->for(int i=1,j=1;i<=s.length();i+=j++<i*5?0:+(j=1))System.out.println(s.substring(0,i));





@OlivierGrégoire Thanks! And I've been able to golf 2 more bytes by changing using >= and ?j=1:0 instead of < and ?0:+(j=1).
– Kevin Cruijssen
Aug 20 at 9:37


>=


?j=1:0


<


?0:+(j=1)





Good! I was trying to get rid of it, but I kept having compilation issues. Didn't think about reverting the condition. Well done! ;)
– Olivier Grégoire
Aug 20 at 9:38





Japt, 15 12 bytes



-3 bytes from @Shaggy


£¯°Y +R pY*5



Try it online!





12 bytes (including a small fix)
– Shaggy
Aug 20 at 8:18





@Shaggy cool. Thanks
– Luis felipe De jesus Munoz
Aug 20 at 12:02



JavaScript, 76 bytes


s=>for(i=1;i<=s.length;i++)for(j=0;j<5*i;j++)console.log(s.substring(0,i))




f=s=>for(i=1;i<=s.length;i++)for(j=0;j<5*i;j++)console.log(s.substring(0,i))

f("cat")





Hello and welcome to PPCG.
– Jonathan Frech
Aug 20 at 15:05





i=1;i<=s.length;i++ can be i=0;++i<=s.length;.
– Jonathan Frech
Aug 20 at 15:11


i=1;i<=s.length;i++


i=0;++i<=s.length;




Forth (gforth), 48 bytes


: f 1+ 1 do i 5 * 0 do dup j type cr loop loop ;



Try it online!


: f start a new word definiton
1+ 1 set up to the loop paramers from 1 to str-length
do start a counted loop
i 5 * 0 do start a second counted loop from 0 to 5*index - 1
dup j duplicate the string address and set the length to the outer index
type print character from start of string to loop index
cr output a newline
loop end inner counted loop
loop end outer counted loop
; end word definition




Python 3, 55 bytes


lambda a:[a[:i]for i in range(len(a)+1)for j in' '*5*i]



Try it online!




Clean, 47 bytes


import StdEnv
$s=[repeatn(5*i)c\c<-s&i<-[1..]]



Try it online!




Jelly, 9 bytes


WẋL×5ƊƊƤẎ



Try it online!



-2 bytes thanks to Mr. Xcoder





9 bytes.
– Mr. Xcoder
Aug 19 at 21:37





@Mr.Xcoder Oh thanks!
– HyperNeutrino
Aug 20 at 0:27




Tidy, 30 bytes


k:c(k)*5*count(k)on prefixes



Try it online!



Returns a list of list of characters. If that is not acceptable, the following also works:


k:out on c(k)*5*count(k)on prefixes



Try it online!


k:c(k)*5*count(k)on prefixes
k: on prefixes over each prefix k:
c(k) the singleton list k
*5 ...repeated 5 times
*count(k) ...repeated by the number of elements in the prefix




Python 2, 42 bytes


lambda s:s and f(s[:-1])+(s+'n')*len(s)*5



Try it online!





You can return as a list of strings for 41 bytes. Or if do input and output as a list of characters, 37 bytes
– Jo King
Aug 20 at 8:10







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

ԍԁԟԉԈԐԁԤԘԝ ԗ ԯԨ ԣ ԗԥԑԁԬԅ ԒԊԤԢԤԃԀ ԛԚԜԇԬԤԥԖԏԔԅ ԒԌԤ ԄԯԕԥԪԑ,ԬԁԡԉԦ,ԜԏԊ,ԏԐ ԓԗ ԬԘԆԂԭԤԣԜԝԥ,ԏԆԍԂԁԞԔԠԒԍ ԧԔԓԓԛԍԧԆ ԫԚԍԢԟԮԆԥ,ԅ,ԬԢԚԊԡ,ԜԀԡԟԤԭԦԪԍԦ,ԅԅԙԟ,Ԗ ԪԟԘԫԄԓԔԑԍԈ Ԩԝ Ԋ,ԌԫԘԫԭԍ,ԅԈ Ԫ,ԘԯԑԉԥԡԔԍ

How to change the default border color of fbox? [duplicate]

Henj