# It took me a lot of time to make this, pls like. (YouTube Comments #1)

Hold up..... this isn't trolling.

# Background

These days on YouTube, comment sections are littered with such patterns:

S
St
Str
Stri
Strin
String
Strin
Stri
Str
St
S


where String is a mere placeholder and refers to any combination of characters. These patterns are usually accompanied by a It took me a lot of time to make this, pls like or something, and often the OP succeeds in amassing a number of likes.

Although you've got a great talent of accumulating upvotes on PPCG with your charming golfing skills, you're definitely not the top choice for making witty remarks or referencing memes in YouTube comment sections. Thus, your constructive comments made with deliberate thought amass a few to no 'likes' on YouTube. You want this to change. So, you resort to making the abovementioned clichéd patterns to achieve your ultimate ambition, but without wasting any time trying to manually write them.

Simply put, your task is to take a string, say s, and output 2*s.length - 1 substrings of s, delimited by a newline, so as to comply with the following pattern:

(for s = "Hello")

H
He
Hel
Hell
Hello
Hell
Hel
He
H


# Input

A single string s. Input defaults of the community apply. You can assume that the input string will only contain printable ASCII characters.

# Output

Several lines separated by a newline, constituting an appropriate pattern as explained above. Output defaults of the community apply. Leading and trailing blank (containing no characters or characters that cannot be seen, like a space) lines in the output are permitted.

# Test Case

A multi-word test case:

Input => "Oh yeah yeah"

Output =>

O
Oh
Oh
Oh y
Oh ye
Oh yea
Oh yeah
Oh yeah
Oh yeah y
Oh yeah ye
Oh yeah yea
Oh yeah yeah
Oh yeah yea
Oh yeah ye
Oh yeah y
Oh yeah
Oh yeah
Oh yea
Oh ye
Oh y
Oh
Oh
O


Note that there are apparent distortions in the above test case's output's shape (for instance, line two and line three of the output appear the same). Those are because we can't see the trailing whitespaces. Your program need NOT to try to fix these distortions.

# Winning Criterion

This is , so the shortest code in bytes in each language wins!

• I am planning to make some more YouTube comments related challenges in the future; hence the YouTube Comments #1 in the title. – Arjun Feb 27 at 10:31
• Is returning a array of lines allowed? – someone Feb 27 at 11:00
• Can we take input as an array of characters and return an array of arrays of characters? – Shaggy Feb 27 at 11:43
• Closely related – Giuseppe Feb 27 at 15:49
• Can the input be ""? What about a single character like "H"? If so, what should be the output for both of those cases? – AdmBorkBork Feb 27 at 20:41

# brainfuck, 32 bytes

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


Try it online!

The same loop is used for both halves of the pattern.

### Explanation:

,             Take first input character as initial line
[             Until line to output is empty:
[<]>        Move to beginning of line
[.>]        Output all characters in line
++++++++++. Output newline
,           Input next character
[>>]        Move two cells right if input character nonzero
<[-]        Otherwise remove last character in line
<           Move to new last character in line
]

• That's just plain awesome. I was trying to do something in brainfuck but it came out about 10 times this long and still didn't work properly. – ElPedro Feb 27 at 22:09
• Never thought I'd see a challenge where the brainfuck answer was actually scoring competitively, awesome work! – Question Marks Feb 28 at 18:01

# JavaScript (ES6), 36 bytes

f=([c,...r],s=
)=>c?s+f(r,s+c)+s:s


Try it online!

### Commented

f = (             // f is a recursive function taking:
//   the input string split into:
[c,             //     c   = next character (may be undefined if we've reached the end)
...r],      //     r[] = array of remaining characters
s = \n        //   the output string s, initialized to a linefeed
) =>              //
c ?             // if c is defined:
s +           //   append s (top of the ASCII art)
f(r, s + c) + //   append the result of a recursive call to f, using r[] and s + c
s             //   append s again (bottom of the ASCII art)
:               // else:
s             //   append s just once (this is the final middle row) and stop recursion

• very nice answer :D – lois6b Feb 27 at 15:38
• @MartinBarker On Windows, I'm using Notepad++ with the default Line Ending turned to Unix (LF). Problem solved once and for all. :) – Arnauld Feb 27 at 17:00
• Awesome! Can you write an explanation for this for those who are complete newbies to JS? – Akhoy Mar 1 at 6:31
• @Akhoy I've added a commented version. – Arnauld Mar 1 at 11:51
• Thank you. A lot clearer now. – Akhoy Mar 1 at 13:25

# 05AB1E (legacy),  4  3 bytes

Crossed out &nbsp;4&nbsp; is no longer 4 :)

η.∊


Explanation:

η     # Get the prefixes of the (implicit) input-string
.∊   # Vertically mirror everything with the last line overlapping
# (which implicitly joins by newlines in the legacy version of 05AB1E)
# (and output the result implicitly)


In the new version of 05AB1E, and explicit » is required after the η, which is why I use the legacy version of 05AB1E here to save a byte.

• Hmm, this seems to 6 bytes in UTF8: \xce\xb7\x2e\xe2\x88\x8a – rubenvb Feb 28 at 17:22
• @rubenvb In UTF-8 it's indeed more. 05AB1E uses, just like some some of the programming languages used in other answers (i.e. Jelly; Japt; Charcoal) it's own source code (which is CP-1252 in the case of 05AB1E), where each of the 256 characters it knows is a single byte. – Kevin Cruijssen Feb 28 at 17:30
• All right, fair enough :). – rubenvb Feb 28 at 17:31
• @KevinCruijssen PHP seems to think that these characters are invalid for CP-1252, but could just be a PHP bug: 3v4l.org/UC1QE – hanshenrik Mar 2 at 10:02
• @hanshenrik Good question. It is indeed not CP-1252, but in fact the 05AB1E encoding, which is the custom encoding it uses. The bytes of this code in hex are 08 2e 17, which you can run and verify with the --osabie flag: tio.run/… – Adnan Mar 2 at 12:20

# IBM PC DOS, 8088 assembly,  44  43

d1ee ad8b d6b4 0948 8af8 8ac8 d0e1 49b3 243a cf7d 024e
4e46 861c cd21 861c 52ba 2901 cd21 5ae2 eac3 0d0a 24


Unassembled:

    SHR  SI, 1              ; point SI to DOS PSP at 80H (SI intialized at 100H)
MOV  DX, SI             ; save start of string pointer
MOV  AH, 9              ; DOS API display string function
DEC  AX                 ; remove leading space from string length
MOV  BH, AL             ; save string len in BH (AL gets mangled by INT 21H,9)
MOV  CL, AL             ; set up loop counter in CL
SHL  CL, 1              ; number of lines = 2 * string length - 1
DEC  CX
MOV  BL, '$' ; end of string marker LINE_LOOP: CMP CL, BH ; if CL >= string length, ascend JGE ASCEND DEC SI ; descend by backing up two places (always increments) DEC SI ; (this is fewer bytes than 'SUB SI, 2' or two branches) ASCEND: INC SI ; increment current string position XCHG BL, [SI] ; swap current string byte with end of string delimiter INT 21H ; write substring to console XCHG BL, [SI] ; restore string byte PUSH DX ; save output string pointer MOV DX, OFFSET CRLF ; load CRLF string INT 21H ; write to console POP DX ; restore output string pointer LOOP LINE_LOOP ; move to next line RET CRLF DB 0DH,0AH,'$'


Explanation

Loop 2 * input length - 1 for each row. The DOS API's string display function (INT 21H,9) writes a $-terminated string to the screen, so each time through the loop the character after the last to be displayed is swapped with the end-of-string terminator. The loop counter is compared with the string length, and if it's greater (meaning the ascending part of the output) the string/swap position is incremented, otherwise it's decremented (actually it's -1-1+1 which is fewer bytes than an if/else branching structure). Standalone executable program, takes input string from command line. Output Output DOS 1.0-compatible version Download YT2.COM (43 bytes) Requires IBM/MS-DOS 2.0+ Download YT1.COM (46 bytes) Any DOS Download YT.COM (original 44 bytes) Any DOS 2+ • Most DOS flavours have SI = 100h upon loading a COM file. This can save you a byte by replacing the first instruction with SHR SI, 1. – gastropner Mar 8 at 14:32 • @gastropner very clever! Turns out the original won't run on DOS 1.0 anyway since it counts on CH being 0 (would cost +2 bytes to initialize, which isn't worth it just for DOS 1). Updated with new version! – gwaugh Mar 8 at 15:11 # Python 2, 60 52 bytes f=lambda s,n=1:s[n:]and[s[:n]]+f(s,n+1)+[s[:n]]or[s]  Try it online! # Python 3.8 (pre-release), 50 bytes f=lambda s,n=1:s>(x:=s[:n])and[x,*f(s,n+1),x]or[s]  Try it online! • Does this depend on a forthcoming feature of 3.8? Which feature? – alexis Feb 27 at 17:58 • @alexis This is using an assignment expression: x:=s[:n]. – Arnauld Feb 27 at 19:35 • Ah, I see it now thanks :-) I've read about the feature before, looking forward to it. Still miss it from my C days... – alexis Feb 28 at 7:37 • These don't print the output though. They just make the array, right? – Jaden Travnik Mar 3 at 17:13 • @JadenTravnik Python automatically dupms the last expression result if running interactively through a console – Xeverous Mar 4 at 23:20 # MATL, 8 bytes nZv"G@:)  Try it online! Please like this post for the smiley :) in the code it took me a lot of time to make. n % Length of the input string Zv % Symmetric range ([1 2 ... n ... 1]) " % For each k in above range G % Push input @: % Push [1 2 ... k] ) % Index  # J, 11 bytes Anonymous tacit prefix function. Returns a space-padded character matrix. [:(}:,|.)]\  Try it online! ]\ the list of prefixes [:() apply the following function to that list |. the reverse list , prepended with }: the curtailed (without last item) list • [:( and }:,| look so sad… – Adám Feb 27 at 11:57 • But it's (}: which is a happy person with a fancy mustache – DonFusili Mar 6 at 9:33 # Perl 6, 31 bytes {[\~](@_)[0...@_-1...0]}o*.comb  Try it online! Anonymous code block that takes a string and returns a list of lines. ### Explanation: { }o*.comb # Pass the list of characters into the codeblock [\~](@_) # Triangular reduce by concatenation # e.g. The list [1,2,3,4] turns into [1,12,123,1234] [0...@_-1 # Return the elements from 0 to length of string minus 1 ...0] # And back down to 0  • It's funny that these days even golfed Perl is among the most readable contestants. – ceased to turn counterclockwis Mar 1 at 6:14 • @ceasedtoturncounterclockwis Well, this is Perl 6. The Perl 5 answer is still unreadable – Jo King Mar 1 at 7:00 # Japt-R, 4 bytes å+ ê  Cumulative reduce on a string. -1 byte thanks to @Shaggy Try it online! • Sceptic about the "-R" that has to be included in the string (without it the output doesnt work) – Flying Thunder Feb 27 at 14:58 • @FlyingThunder Be a skeptic no more :) see here – Quintec Feb 27 at 15:11 • @Quintec, I've taken to linking the flags in my solution headers to that meta post to try to preempt these sorts of comments. – Shaggy Feb 27 at 18:02 • Pretty sure convention is <language> + -flag or <language> -flag. Also, :| I forgot cumulative reduce was a thing, I swear I skipped over it every time I saw it – ASCII-only Mar 1 at 11:53 • @ASCII-only Same, I only remembered it because I was thinking how I would solve this in APL and said "I wonder if Japt has this builtin". Also, didn't I use <language> -flag? – Quintec Mar 1 at 14:01 # Japt-R, 9 7 bytes -2 bytes thanks to Shaggy Êõ@¯XÃê  Try it online! • 7 bytes – Shaggy Feb 27 at 11:43 • @Shaggy oh wait... Ã is a thing – ASCII-only Feb 27 at 11:47 • Another 300 rep on its way as soon as this question is eligible for a bounty. – Shaggy Feb 27 at 13:06 • 5 bytes? (different approach) – Quintec Feb 27 at 14:14 • @Quintec, cumulative reduce works on strings, too, so you don't need to split at the start. I'd also say that's different enough to warrant posting it yourself. – Shaggy Feb 27 at 14:38 # Perl 5 (-p), 26 bytes s,.,$\=$.$/.$\;"$$& ",ge  TIO # Haskell, 5250 44 bytes f x=unlines$init<>reverse$scanr(\_->init)x x  Try it online! • Welcome to the site. inits requires an import to be used so you are going to need to add import Data.List or something similar. – Sriotchilism O'Zaic Feb 27 at 21:16 • @SriotchilismO'Zaic Wasn't sure if that was necessary to count or not. Added, thanks! – Joseph Sible Feb 27 at 22:04 • Also I should mention we have a chat room for talking Haskell golfing. If you have any thoughts or questions that's a great place. – Sriotchilism O'Zaic Feb 27 at 22:21 • I can't believe you came up with exactly what I was going to post: import Data.List putStr.unlines.((++)<*>reverse.init).tail.inits – Axman6 Feb 28 at 5:05 # R, 796562 58 bytes write(substring(s<-scan(,""),1,c(1:(r=nchar(s)),r-1:r)),1)  Try it online! -14 by Giuseppe's superior function knowledge -3 with cleaner indexing -4 thanks to Nick Kennedy and Giuseppe's move to scan and write Avoiding loops (and substr) is nice. • loops are thoroughly unnecessary, as is sapply -- substring will do what you want (with an additional trailing empty line), and for 65 bytes! I definitely wouldn't have thought of substring if I hadn't seen your nice use of substr here. – Giuseppe Feb 27 at 15:53 • Haha, good catch! I think I've learned more about alternate functions for the same job from your edits than anywhere else at this point. – CriminallyVulgar Feb 27 at 16:01 • Haha, R has a stupid amount of synonyms with subtle differences. Every time I feel like I know the best tool for the job, I find something else that's slightly better in a weird edge case... – Giuseppe Feb 27 at 16:06 • How about Try it online! using scan and write? Only 59 bytes! – Nick Kennedy Feb 27 at 18:49 • @NickKennedy 58 bytes if you replace "" with 1. – Giuseppe Feb 27 at 19:10 # Jelly, 5 4 bytes -1 byte thanks to @JonathanAllan! ¹ƤŒḄ  Try it online! I think this is my second Jelly answer? I don't know if this is optimal. I am more convinced of it being optimal. Returns an array of lines. ## Explanation ¹ƤŒḄ input: "Hi!" ¹Ƥ prefixes of the input: [["H"], ["H", "i"], ["H", "i", "!"]] ŒḄ bounce, using each array: [["H"], ["H", "i"], ["H", "i", "!"], ["H", "i"], ["H"]]  Another approach, proposed by @JonathanAllan, is ;\ŒḄ, which cumulatively reduces (\) concatenation (;), which is another way to generate prefixes. • We are allowed to yield an array of lines, so you can bump Y out of the code (I'd make the footer either ÇY or ÇŒṘ to avoid a full-program's implicit smashing print). On a side-note this is also equivalently implemented as ;\ŒḄ for the same byte-count (also you can pass the argument as"blah" as Jelly interprets this as a list of characters - yours is actually a list of lists of characters, as you'll see if you make the footer ÇŒṘ) – Jonathan Allan Feb 28 at 13:50 • @JonathanAllan thanks! very interesting :) – Conor O'Brien Feb 28 at 17:15 # Charcoal, 5 bytes Ｇ^Ｌθθ  Try it online! Link is to verbose version of code. Explanation: Ｇ draws a filled polygon, ^ specifies that the sides are down right and down left (the polygon then automatically closes itself), Ｌθ specifies the length of those sides as being the length of the original input and the final θ specifies the fill string. # Python 3.8 (pre-release), 48 bytes lambda s,r='':(l:=[r:=r+c for c in s])+l[-2::-1]  Try it online! Uses assignment expressions with := to accumulate a list of prefixes and then again to save the result to concatenate its reverse (without the first char). # Python 2, 51 bytes f=lambda s,l=[]:s and f(s[:-1],[s]+l)or l+l[-2::-1]  Try it online! We almost have the following nice 45-byte solution, but it has the original string twice and I don't see a short way to fix this. f=lambda s,l=[]:s and f(s[:-1],[s]+l+[s])or l  Try it online! • Wouldn't you need to add some newline and print to get the desired output? – Jaden Travnik Mar 3 at 17:16 • Something like print('\n'.join(f(s))) ? – Jaden Travnik Mar 3 at 17:22 • @JadenTravnik The community defaults (which this challenge follows) allow for functions in addition to programs. And the challenge author said in the comments that they are OK with a list of strings within joining as allowed by default, though I myself don't like this as a default and have downvoted it. See also the Python rules summary. – xnor Mar 3 at 17:34 • Huh. Ok, thanks for pointing that out. Im new ¯_(ツ)_/¯. If thats the case, here is a competing 45-byte solution: x=[s[:i+1]for i in range(len(s))];x+x[-2::-1] – Jaden Travnik Mar 3 at 17:42 • @JadenTravnik No problem, the rules are unfortunately scattered over the place. Your example though is a snippet which are not allowed. It needs to do input and output like s=input();x=[s[:i+1]for i in range(len(s))];print x+x[-2::-1]. See the examples at the top here. – xnor Mar 3 at 17:56 # C# (Visual C# Interactive Compiler), 1231099484 74 bytes Assumes we can return a char array array (I believe we can, as a char array is a valid representation for a string and a string array is a valid representation for multiple lines) a=>new int[a.Length*2-1].Select((b,i)=>a.SkipLast(Math.Abs(a.Length-i-1)))  Try it online! # Attache, 15 bytes Bounce@Prefixes  Try it online! Pretty simple. Bounces (appends reverse without center) the Prefixes of the input. Alternatively, 21 bytes: Bounce@{_[0..0:~-#_]}, re-implementing prefix. # Brachylog (v2), 6 bytes a₀ᶠ⊆.↔  Try it online! Function submission, returning an array of lines. Loosely based on @Fatalize's answer. ## Explanation a₀ᶠ⊆.↔ .↔ Find a palindrome ⊆ that contains, in order, ᶠ all a₀ prefixes of {the input}  Tiebreak order here is set by the ⊆, which, when used with this flow pattern, prefers the shortest possible output, tiebroken by placing the given elements as early as possible. The shortest possible output is what we want here (due to it not being possible to have any duplicate prefixes), and placing the given elements (i.e. the prefixes) as early as possible will place them in the first half (rounded up) of the output. Given that we're also requiring them to be placed in the same order, we happen to get exactly the pattern we need even though the description we gave Brachylog is very general; the tiebreaks happen to work out exactly right, causing Brachylog to pick the output we want rather than some other output that obeys the description. # PowerShell, 8987 66 bytes -2 bytes thanks to @AdmBorkBork param($a)0..($d=$a.Length-1)|%{$b+=,-join$a[0..$_]};$b+$b[--$d..0]


Try it online!

It actually didn't work as specified before, sorry about that! I've edited it and also managed to shave some bytes off.

• You can --$d instead of ($d-1) to save a couple at the end. – AdmBorkBork Feb 27 at 16:14
• @AdmBorkBork Thanks. – Gabriel Mills Feb 27 at 22:19
• This doesn't work for single-character input, sadly. – AdmBorkBork Feb 28 at 15:09

($l=$args|% t*y|%{($s+=$_);++$i})+$l[$i..0]|gu  Try it online! # PowerShell, 42 bytes (YouTube special, dirty) It is known that the maximum length of a comment on youtube is 10,000 characters. Ok, use this as the upper limit. ($l=$args|% t*y|%{($s+=$_)})+$l[1e4..0]|gu


Try it online!

# APL (Dyalog Unicode), 9 bytesSBCS

Anonymous tacit prefix function. Returns list of strings.

(⊢,1↓⌽),\


Try it online!

,\ the list of prefixes (lit, the cumulative concatenation)

() apply the following function to that list:

⌽ the reversed list

1↓ drop the first item

, prepend

⊢ the unmodified list

# Ruby, 5142 40 bytes

f=->s,i=1{s[i]?[t=s[0,i],*f[s,i+1],t]:s}


Try it online!

Thanks to Doorknob for -2 bytes.

• You can save 2 bytes by replacing ... with , – Doorknob Feb 27 at 13:17

# JavaScript (Node.js), 90 bytes

This can probably be golfed alot more, Arnauld already has a way shorter one but I had fun atleast!

s=>{a=[];for(c=s.length-1;c--;)a[c]=s.slice(0,c+1);return[...a,s,...a.reverse()].join\n}


Try it online!

# SNOBOL4 (CSNOBOL4), 118 bytes

	N =INPUT
L =1
1	X =LT(X,SIZE(N)) X + 1	:F(D)
/^$/{x;q} H G bx  Try it online! # Explanation At the beginning of each iteration of the loop, pattern space is some "central chunk" of the desired output, and each loop adds a shortened copy to the top and bottom. :x h Copy the current chunk to hold space s/.\n.*\|.$//      Remove the last letter of the first line, and all other lines (if there are any)
/^$/{x;q} If pattern space is empty we're done; output hold space H Add the shortened line to the end of hold space G and add the new hold space to pattern space. bx  • Nice one, but the the middle line (the full original input) seems to be output 3 times. At least with GNU sed. Same on TIO. Which sed implementation you use and how you pass it the input? (BTW, changing the substitution to s/.\n.*\|.$// fixes it.) – manatwork Feb 28 at 13:12
• Ah, you're right. It's not a problem with my sed implementation (using GNU version 4.2.1) , I just didn't notice the bug. I've played around with some other fixes and can't find anything that adds fewer than four bytes so I'm adopting your fix, thank you. – Sophia Lechner Feb 28 at 18:22

# Python 2, 131100 84 bytes

My first answer on Code Golf!

-47 bytes overall thanks to @SriotchilismO'Zaic

a,b=[],len(x)
for i in range(2*b-1):
if i<b:a+=x[i]
else:a=a[:-1]
print''.join(a)


Try it online!

• Welcome to PCG! Be sure to read the tour and code of conduct. Good solution! – akozi Feb 28 at 17:02
• For python you can use ;s instead of newlines to avoid the indentation. Also no need for spaces between print and '' – Sriotchilism O'Zaic Feb 28 at 17:20
• Thanks for the tips @SriotchilismO'Zaic, really helped reduce my byte count! – Yoni Matz Feb 28 at 20:14
• And one last thing, if you make a a string rather than a list, you no longer need the join at all and you can just print a. – Sriotchilism O'Zaic Feb 28 at 21:45
• Invalid, it needs to be a full program or function, whereas you assume input is in x. – ASCII-only Mar 1 at 4:32

# J, 12 bytes

]\,[:}.@|.]\


Try it online!

Still 1 byte longer than Adám's

# K (oK), 12 11 bytes

-1 byte thanks to ngn

{x,1_|x}@,\


Try it online!

• Did I outgolf the master‽ – Adám Feb 27 at 11:56
• @Adám I'm far from being a J master :) There are many J coders here better than I am. – Galen Ivanov Feb 27 at 12:00
• -1 byte for oK: {x,1_|x}@,\  – ngn Feb 28 at 22:31
• @ngn Thank you! – Galen Ivanov Mar 1 at 4:51

## protected by Community♦Feb 28 at 17:45

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).