82
\$\begingroup\$

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.


The Task

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!

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

67 Answers 67

4
\$\begingroup\$

C (gcc), 68 67 64 59 bytes

thanks @ceilingcat for -6 thanks @gastropner for -5

i,j;f(char*s){for(j=1;i+=j;puts(""))j-=2*!s[write(1,s,i)];}

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Octave, 58 bytes

for k=1:(n=nnz(s=input(''))*2)-1
disp(s(1:min(k,n-k)))
end

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ I came up with essentially the same answer in MATLAB before I saw yours, but you get to take shortcuts in Octave with those compound assignments saving several bytes... I did briefly consider if any char maps to zero, such that nnz would miss it? \$\endgroup\$ – Wolfie Mar 1 at 8:58
  • \$\begingroup\$ @Wolfie Somehow I assumed the input would not contain char(0), but you are right, it might be the case. I've asked for the OP if we can assume the standard ASCII range 32--127 \$\endgroup\$ – Luis Mendo Mar 1 at 10:28
  • \$\begingroup\$ @Wolfie Confirmed: only printable ASCII \$\endgroup\$ – Luis Mendo Mar 4 at 9:48
3
\$\begingroup\$

C# (Visual C# Interactive Compiler), 82 81 bytes

x=>{for(int l=x.Length,i=0;i<l*2-1;)WriteLine(x.Substring(0,l-Math.Abs(++i-l)));}

Try it online!

String as input and output to std

\$\endgroup\$
3
\$\begingroup\$

BASH (+ GNU coreutils) 72 bytes

Takes input string from STDIN (one line)

read s;for i in `seq ${#s};seq $((${#s}-1)) -1 1`;do echo ${s:0:$i};done

example:

echo "Oh yeah yeah" | ./script.sh

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

Explanation:

# read string from STDIN into variable $s
read s

# `seq ${#s}` : sequence of numbers from 1 to length of string followed by
# `seq $((${#s}-1)) -1 1` : sequence of numbers from length-1 downto 1

# loop through sequence
for i in `seq ${#s};seq $((${#s}-1)) -1 1`;do

    # print substring of $s from position 0 to i
    echo ${s:0:$i}

# end of loop
done
\$\endgroup\$
  • \$\begingroup\$ You can squish it down to 67 bytes... read s;for i in `seq ${#s};seq $[${#s}-1] -1 1`;{ echo ${s:0:$i};} using some bash golf tricks. Example: ideone.com/Pw94LT \$\endgroup\$ – roblogic Mar 23 at 5:13
  • \$\begingroup\$ I golfed it down to 65 in bash using weird iterators! Here's my solution... tio.run \$\endgroup\$ – roblogic Mar 23 at 14:05
3
\$\begingroup\$

[Assembly (nasm, x64, Linux)], 35 32 bytes

This is a function that takes a string (Pointer in RSI) and it's length (number in ebp), and outputs the required string to STDOUT.

EDI and EDX MUST be 0


ytc:
	;Actual setup
	inc ebp
	inc edi ;FD for STDOUT
	push rdi ;Value to add/subtract
	mov bl, 0Ah
.lp:
	add edx, [rsp] ;Str Length +- 1
	jz .end
	cmp edx, ebp
	jne .clp
	push -1
.clp:
	xchg [rsi+rdx-1], bl
	mov al, 1
	syscall
	xchg [rsi+rdx-1], bl
	jmp .lp
.end:
	ret

Try it online!

\$\endgroup\$
3
\$\begingroup\$

C (gcc), 62 60 58 bytes

-2 bytes by using the write() approach of jaeyong-sung's answer.

i,d;f(char*s){for(d=1;write(1,s,i+=d-=!s[i]*2);puts(""));}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Brachylog, 8 bytes

a₀ᶠ;Lc.↔

Try it online!

Explanation

a₀ᶠ          Find all prefixes of the input
   ;Lc.      The output is that list of prefixes with something unknown appended at the end
      .↔     The output reversed is itself (i.e. it's a palindrome)
\$\endgroup\$
2
\$\begingroup\$

R, 86 bytes

x=utf8ToInt(scan(,''))
for(i in c(y<-1:sum(x|1),rev(y)[-1]))cat(intToUtf8(x[1:i]),"
")

Try it online!

I'm learning more and more about better ways to manipulate strings in R, so I'm somewhat proud of this answer. The only part I don't like is the for loop portion, which I feel could definitely be golfed.

\$\endgroup\$
  • 1
    \$\begingroup\$ what about y<-seq(x)? \$\endgroup\$ – Droplet Feb 27 at 17:10
  • 2
    \$\begingroup\$ @Droplet you have to be quite careful about seq(x)! seq(x) behaves like seq_along(x) so long as x is not an integer or double of length 1. In that case, if x=c(65), for example, then seq(x) instead returns 1:x, which would not be the right behavior here. It's rather frustrating! \$\endgroup\$ – Giuseppe Feb 27 at 18:09
  • \$\begingroup\$ You're right, I didn't think of the case when s was just one letter \$\endgroup\$ – Droplet Feb 28 at 9:57
  • \$\begingroup\$ is the purpose of x=utf8ToInt(scan(,''))? \$\endgroup\$ – dylanjm Mar 20 at 22:02
  • 1
    \$\begingroup\$ neat y<-seq(a=x) trick that somebody introduced (I forget who) try it online for -2 bytes! \$\endgroup\$ – Giuseppe Apr 4 at 22:14
2
\$\begingroup\$

MBASIC, 103 bytes

1 INPUT S$:N=1
2 PRINT LEFT$(S$,N):IF N<LEN(S$) THEN N=N+1:GOTO 2
3 N=N-1:PRINT LEFT$(S$,N):IF N>1 THEN 3
\$\endgroup\$
2
\$\begingroup\$

Pyke, 6 bytes

BE 27 4F 5F 2B 58

Try it here!

        - input() (implicit)
.>      - prefixes(^) (1 byte)
  'O_   - ^[:-1], reversed(^)
     +  - [^]
      X - "\n".join(reversed(^))
\$\endgroup\$
2
\$\begingroup\$

Haskell, 36 bytes

foldr(\h l->(h:)<$>[]:l++min[[]]l)[]

Try it online!

Outputs a list of lines.

Haskell, 37 bytes

f[c]=[[c]]
f(h:t)=(h:)<$>"":f t++[""]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

MathGolf, 7 bytes

£rñ{l<n

Try it online!

Explanation

£         length of array/string with pop
 r        range(0, n)
  ñ       pop(a), push palindromize(a) string/list/number
   {      start block or arbitrary length
    l     read string from input
     <    slice input string at index
      n   newline char
\$\endgroup\$
2
\$\begingroup\$

><>,  44  41 bytes

i:0(?^l&}21.>ao&~
:o}1&:1-&) ?^
l&21.>~{~

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Kotlin, 62 bytes

{s->s.indices.map{s.take(it+1)}.let{it+it.reversed().drop(1)}}

Could probably be golfed more, but this is what I came up with.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

PHP, 79 bytes

function y($s,$l=1){echo$t=substr($s,0,$l)."
",$l<strlen($s)?y($s,$l+1).$t:'';}

Try it online!

Recursive in PHP as a function. Ungolfed version:

function y( $s, $l=1 ) {
    echo $t = substr( $s, 0, $l ) . "\n";
    if ( $l < strlen( $s ) ) {
        y( $s, $l+1 );
        echo $t;
    }
}

Call as y('String') outputs:

S
St
Str
Stri
Strin
String
Strin
Stri
Str
St
S

Or 69 bytes iterative with php -nF input as STDIN (basically a port of several other answers).

while(++$x<2*$l=strlen($s=$argn))echo substr($s,0,$l-abs($x-$l)),"
";

Try it online!

\$\endgroup\$
2
\$\begingroup\$

VBA, 54 51 Bytes

(-3 bytes now that leading & trailing 0-character lines are confirmed as permitted)

x=Len([A1]):For i=-x To x:?Left([A1],x-abs(i)):Next

Just a simple loop from -Length to Length, omitting that many Absolute characters from the end each time

Input is cell A1 of the ActiveSheet. Output and Code are in the Immediate window

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

C# (Visual C# Interactive Compiler), 76 bytes

x=>{for(int i=0,s=1;s+i>0;s=i<x.Length?s:-s)WriteLine(x.Substring(0,i+=s));}

Try it online!

Using an iterative approach, as opposed to LINQ.

I did not realize until after I posted, but my answer is pretty similar to aloisdg's answer. Although they are different enough, I might just leave mine too :)

\$\endgroup\$
  • 1
    \$\begingroup\$ Gald you posted it. I like it! \$\endgroup\$ – aloisdg Feb 27 at 22:05
1
\$\begingroup\$

Python 2, 68 bytes

i,j=input(),''
j=[i[:x]for x in range(1,len(i))]
print j+[i]+j[::-1]

Try it online!

Longer than the other Python answers but just another way of doing it.

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

Java (JDK), 86 bytes

s->{for(int i=0,l=s.length();++i<2*l;)System.out.println(s.substring(0,i<l?i:2*l-i));}

Try it online!

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

Julia, 40 bytes

s->(a=cumprod([s...]);[a;a[end-1:-1:1]])

Try it online!

Gets the first half by taking the cumulative product (* is string concatenation in Julia) of the array of characters, then adds this array to itself reversed minus the first element.

Thanks to @Kirill L. for 4 bytes.

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

APL(NARS), 24 char, 48 bytes

{⊃{w[⍵]}¨k,1↓⌽k←⍳¨⍳≢w←⍵}

test and how to use it:

  h←{⊃{w[⍵]}¨k,1↓⌽k←⍳¨⍳≢w←⍵}
        h ,'1'
1
  h '12'
1 
12
1 
  h '123'
1  
12 
123
12 
1  

comment: it would build one array of ranges [(1) (1 2) (1 2 3) ecc] and the code pass each of them to the function {w[⍵]}

\$\endgroup\$
  • \$\begingroup\$ Use and a train, and return a vector of vectors to save: {(⊂¨(+,1↓⌽)⍳¨⍳≢⍵)⌷¨⊂⍵} Try it online! \$\endgroup\$ – Adám Mar 5 at 23:57
1
\$\begingroup\$

Wolfram Language (Mathematica), 63 bytes

(L=2StringLength@#;Do[Print@StringTake[#,Min[n,L-n]],{n,L-1}])&

Try it online!

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

Factor, 77 bytes

: f ( s -- ) dup length [1,b] dup reverse 1 tail append [ head ] with map . ;

Try it online!

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

Wolfram Language (Mathematica), 100 bytes

StringJoin[#~Join~Reverse[#][[2;;]]&[Append[Take[#,i],"\n"]~Table~{i,1,Length[#]}&[Characters[#]]]]&

Try it online!

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

Nim, 83 76 bytes

let s=readline(stdin)
let l=len(s)
for a in 1..l*2-1:echo(s[0..<l-abs(a-l)])

Try it online!

My first time golfing in Nim. All inputs are welcome!

This is a port of my F# and C# answer.

  • -7 bytes by using the [a..<b] instead of substr() (source)
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 91 bytes

a=>{r=[];for(i=0;++i<a.length;)r.push(a.slice(0,i));return[...r,a,...r.reverse()].join`\n`}

Try it online!

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

Python 2, 122 90 bytes

A worse solution of @xnor's

u=lambda n,s,b:s[:b-abs(n-b)]+'\n'+u(n+1,s,b)if n<2*b else""
def c(w):print(u(0,w,len(w)))

Try it online!

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

Röda, 37 bytes

f s{{seq 1,#s-1;seq#s,1}|[s[:_],"
"]}

Try it online!

Explanation:

f s{ /* Function f(s) */
 {
  seq 1,#s-1; /* Push numbers 1..#s-1 to the stream (#s = length of s) */
  seq #s,1    /*   --..--     #s..1    --..-- */
 }|
 [       /* Print the following things for each _ in the stream: */
  s[:_], /*  Substring of s from 0 to _ */
  "
"        /*  Newline */
 ]
}
\$\endgroup\$
1
\$\begingroup\$

C, 78 bytes

#define f;printf("%.*s\n",i,d));
i;y(char*d){for(;i++<strlen(d)f for(i--;i--f}

Friends say - "that's some serious macro abuse there"

\$\endgroup\$
  • \$\begingroup\$ 73 \$\endgroup\$ – ASCII-only Apr 4 at 5:31
1
\$\begingroup\$

Pyth, 10 bytes

j+._zt_._z

Try it online!

j          # Join the final array with newlines and print
 +         # Join the two resulting arrays: 
  ._z      #   1. All prefixes of the input (z)
     t     #   2. Remove the first element (full word)
      _    #      of the reverse 
       ._z #      of all prefixes of the input (z)

Thanks to ASCII-only for helping get the bytes down!

\$\endgroup\$
  • \$\begingroup\$ 16 \$\endgroup\$ – ASCII-only Apr 4 at 5:14
  • \$\begingroup\$ yours can also be 16 \$\endgroup\$ – ASCII-only Apr 4 at 5:16
  • 1
    \$\begingroup\$ 10 \$\endgroup\$ – ASCII-only Apr 4 at 5:24
  • \$\begingroup\$ @ASCII-only The 16 ones have a trailing empty line, I didn't realize that was allowed so I had had added the Ik to fix that. That 10-byte entry is seriously impressive, why not submit it as a seperate answer? \$\endgroup\$ – GammaGames Apr 4 at 14:09
  • \$\begingroup\$ 1. i don't mind if you post it, 2. don't have time today, 3. it's 90% done by a builtin lol, i don't even know Pyth well \$\endgroup\$ – ASCII-only Apr 4 at 14:11

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

Would you like to answer one of these unanswered questions instead?

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