104
\$\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\$
12
  • 24
    \$\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, 2019 at 10:31
  • 1
    \$\begingroup\$ Is returning a array of lines allowed? \$\endgroup\$ Feb 27, 2019 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, 2019 at 11:43
  • 3
    \$\begingroup\$ Closely related \$\endgroup\$
    – Giuseppe
    Feb 27, 2019 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\$ Feb 27, 2019 at 20:41

90 Answers 90

1 2
3
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\$

Gaia, 3 bytes

…ṫṣ

Try it online!

As simple as it gets.

…	| prefixes
 ṫ	| palindromize
  ṣ	| join with newlines
\$\endgroup\$
2
  • \$\begingroup\$ Bytes? These look like Unicode characters to me. \$\endgroup\$ Sep 2, 2019 at 13:05
  • \$\begingroup\$ @MarkJeronimus Gaia, like some other golfing languages, uses a custom code page so that each instruction is a single byte. \$\endgroup\$
    – Giuseppe
    Sep 2, 2019 at 19:04
1
\$\begingroup\$

Zsh, 60 bytes

for c (${(s::Oa)1})(($#a))&&a=($c $c$^a $c)||a=$c
<<<${(F)a}

Try it online!

for c (${(s::Oa)1})          # (s::) splits the first parameter, (Oa) reverses order
    (( $#a )) &&             # if $a is not empty, then
        a=($c $c$^a $c) ||   # ...set a to the current character, then the array with
                             # the current character prepended to each element, else
        a=$c                 # ...set a to the current character
<<< ${(F)a}                  # print a; (F) joins on newlines
\$\endgroup\$
1
\$\begingroup\$

Python 2, 52 bytes

f=lambda s,i=1:s[i:]and[s[:i]]+f(s,i+1)+[s[:i]]or[s]

Try it online!

Returns a list of strings.

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

CJam, 28 29 bytes

l_,{_A)<oNo}fA_,{_A)~<oNo}fA;

My first CJam answer, so this can probably be golfed quite a lot

Edit: actually made it work correctly, at the cost of a byte

Try it online!

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

Wolfram Language (Mathematica), 59 bytes

Print/@Table[#~StringDrop~-Abs@i,{i,l=-StringLength@#,-l}]&

Try it online!


Taking input as a list of characters, and returning a list of character lists, 39 bytes:

Table[#~Drop~-Abs@i,{i,l=-Tr[1^#],-l}]&

Try it online!

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

Brain-Flak, 254 bytes

<>(<()>)<>{({}(<()>))<>{({}<>)<>}{}((()()()()()){})(<()>)<>{({}(<()>))(({}<>)<{({}<>)<>}>{})(<()>)<>{({}<>)<>}{}}{}}<>{({}<>)(<()>)<>{({}<>)<>}{}((()()()()()){})(<()>)<>{({}(<()>))(({}<>)<{({}<>)<>}>{})(<()>)<>{({}<>)<>}{}}{}<>}<>{{}}<>{}{}{({}<>)<>}<>{}

Try it online!

Harder than expected (or maybe i'm just not very talented in Brain-Flak ^^)

Explanation:

<>(<()>)<>              push 0 on second stack

                        ### copy words with increasing letter count to second stack
{                       while letters on stack
  ({}(<()>))            push 0 after first letter
  <>{                   move letters up to next 0 from second to first stack
    ({}<>)<>
  }
  {}                    pop 0
  ((()()()()()){})      append newline
  (<()>)                push new 0
  <>
                        ### append word from first to second stack
  {                     While letters on stack
    ({}(<()>))          push 0 after first letter
    (                   move letter on "third" stack for later use
      ({}<>)            move letter to other stack
      <{                move letters up to next 0 from second to first stack
        ({}<>)<>
      }>
      {}                pop 0
    )                   save letter from "third" stack
    (<()>)              push new 0
    <>{                 move letters up to next 0 from second to first stack
      ({}<>)<>
    }
    {}                  pop 0
  }
  {}                    pop 0
}
<>

                        ### copy words with decreasing letter count to second stack
{                       while letters on second stack
  ({}<>)(<()>)<>        move letter and 0 on first stack
  {                     move letters up to next 0 from second to first stack
    ({}<>)<>
  }
  {}                    pop 0
  ((()()()()()){})      append newline
  (<()>)                push new 0
  <>
                        ### append word from first to second stack
  {                     While letters on stack
    ({}(<()>))          push 0 after first letter
    (                   move letter on "third" stack for later use
      ({}<>)            move letter to other stack
      <{                move letters up to next 0 from second to first stack
        ({}<>)<>
      }>
      {}                pop 0
    )                   save letter from "third" stack
    (<()>)              push new 0
    <>{                 move letters up to next 0 from second to first stack
      ({}<>)<>
    }
    {}                  pop 0
  }
  {}                    pop 0
  <>
}

                        ### Tidy up
<>
{{}}                    delete input
<>
{}{}                    pop 0 and newline
{({}<>)<>}              move everything from second to first stack
<>
{}                      pop newline
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 107 106 bytes

(s)->{int l=s.length(),i=0;var r=new String[2*l-1];for(;i<l;r[i]=r[2*l-i-2]=s.substring(0,++i));return r;}

Loops over the characters of the input string and fills the resulting array from both sides.

Try it online!

107 -> 106: i=0 at initialisation so removed from for loop

\$\endgroup\$
1
  • \$\begingroup\$ Nice golf! +1'ed \$\endgroup\$
    – Arjun
    Nov 3, 2020 at 13:41
1
\$\begingroup\$

Python 2, 68 63 bytes

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

Try it online!

-5 thanks to @pppery for spotting an unneeded variable declaration.

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

\$\endgroup\$
2
  • \$\begingroup\$ 63 bytes \$\endgroup\$ Nov 3, 2020 at 23:38
  • \$\begingroup\$ @pppery Thanks for that and well spotted. Leftover from something I had tried earlier! \$\endgroup\$
    – ElPedro
    Nov 4, 2020 at 11:12
1
\$\begingroup\$

Ly, 43 bytes

0>&ir[sp<l&:rp[o]r(10)o>]<rpr[p&s&o(10)o&l]

Try it online!

The logic here is to go through each character (codepoint in Ly) of the input string, add it to a second stack, print the accumulated characters, then go back to the input. Once the input is exhausted, start with the "whole string" copy and do the reverse (remove a character, print, loop) until it's empty.

0>&ir[sp<l&:rp[o]r(10)o>]<rpr[p&s&o(10)o&l]  #
0                                            # Push 0 on the stack
 >                                           # Switch to stack on the right
  &i                                         # Read input onto the stack as codepoints
    r                                        # Reverse the stack
     [                  ]                    # Loop until stack is empty
      s                                      # Stash the current char
       p                                     # Delete it from the stack
        <                                    # Switch to stack on the left
         l                                   # Load the stashed character
          &:                                 # Duplicate stack on itself
            rp                               # Reverse stack, pop the top (0)
              [o]                            # Print stack until we hit a 0
                 r(10)o                      # Reverse the stack, print a LF
                       >                     # Switch to stack on the right
                         <                   # Time to shrink... Switch left
                          rpr                # Remove 0 at front of stack
                             [            ]  # While stack not empty
                              p              # Delete one character
                               &s            # Stash the whole stack
                                 &o          # Print the stack in order
                                   (10)o     # Print a LF
                                        &l   # Restore the stack
     
\$\endgroup\$
1
\$\begingroup\$

Python 3.8 (pre-release), 96 bytes

def f(s):
    for i in (a:=range(len(s))):print(s[:i+1])
    for i in a[::-1][1:]:print(s[:i+1])

Try it online!

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

JavaScript (ES6), 64 bytes

Here's another JS solution:

s=>(l=s.length,f=i=>i<l*2?s.slice(0,i>l?l-i:i)+`
`+f(i+1):"")(1)
\$\endgroup\$
1
\$\begingroup\$

Python 3, 65 63 bytes

Returns a list of lines.

lambda s:[s[:[i,2*len(s)-i][i>len(s)]]for i in range(len(s)*2)]

Try it online!

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

Red, 78 bytes

func[s][repeat n l: length? s[print copy/part s n]loop l[take/last s print s]]

Try it online!

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

x86 machine code (Linux), 53 bytes

00000000: 89cf 31d2 4252 e814 0000 005a 803c 1100  ..1.BR.....Z.<..
00000010: 75f2 4a52 e806 0000 005a 09d2 75f4 c36a  u.JR.....Z..u..j
00000020: 015b 6a04 58cd 806a 0ab2 0189 e1b0 04cd  .[j.X..j........
00000030: 805e 89f9 c3                             .^...

Assembly:

section .text
	global func
func:				;Main function with args: char* ecx
					;Clear registers
	mov edi, ecx			;push pointer to original string
	xor edx, edx			;message length, start at 0
	loop_a:				;Increasing length loop:
		inc edx				;increment message length
		push edx			;save message length
		call print_text			;print string with newline
		pop edx				;get message length
		cmp byte [ecx + edx], 0		;If not at end of string:
		jne loop_a			;continue looping
	loop_b:				;Decreasing length loop:
		dec edx				;decrement message length
		push edx			;save message length
		call print_text			;print string with newline
		pop edx				;get message length
		or edx, edx			;If edx != 0:
		jne loop_b			;Continue loop
	ret

print_text:			;Function to print string (pointer in ecx) with newline:
	push 1
	pop ebx				;fd of stdout
	push 4
	pop eax				;syscall #4 (write)
	int 0x80			;run syscall (msg is in ecx)
	push 0xA			;push newline
	mov dl, 1			;set message length to 1
	mov ecx, esp			;set pointer for syscall to top of stack
	mov al, 4			;syscall #4 (write)
	int 0x80			;run syscall
	pop esi				;reset stack pointer
	mov ecx, edi			;get pointer to original string
	ret

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Tip: try and merge the increasing and decreasing length loops, like i did in my x64 answer. \$\endgroup\$ Mar 6, 2019 at 23:47
0
\$\begingroup\$

SAP ABAP (Unicode), 143 bytes

FORM i USING s.DATA(w) = 2 * strlen( s ).WHILE w > 0.w = w - 1.IF w < strlen( s ).WRITE:/ s(w).ELSE.WRITE:/ s(sy-index).ENDIF.ENDWHILE.ENDFORM.

Pretty straightforward subroutine. I'm using ABAP's substring access var+offset(length) and the system variable sy-index, which represents the index of the current loop. Other than that it's probably pretty self-explanatory, even though it's ABAP.


SAP ABAP (Non-Unicode), 141 bytes

FORM i USING s.DATA(w) = 2 * strlen( s ).WHILE w > 0.w = w - 1.IF w < strlen( s ).WRITE:/ s(w).ELSE.WRITE:/ s(sy(10)).ENDIF.ENDWHILE.ENDFORM.

Saving two bytes here by accessing the index component of sy like a substring, despite it being an integer value. In Unicode systems, characters are obviously multi-byte values, therefore using offsets is not allowed in mixed-type structures like sy. However, in a non-Unicode (ASCII-based) system, both digits of a number and characters are represented as one byte each, and offsets are allowed for structures like sy.

Conveniently index is the first 10-byte component of structure sy, so we don't need to use an offset. Otherwise we'd not be able to save anything here, as sy+x(10) is just as long as sy-index - or even longer if the offset was >= 10.


Output of both programs is obviously the same, screenshot below.

Output

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

Java 8, 92 91 bytes

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

Try it online!

-1 byte by using a for loop instead of a while

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

T-SQL query, 119 bytes

SELECT left(@,n)FROM(SELECT*,number/2+1n,len(@)k,number%2-.5m
FROM spt_values)x
WHERE type='P'and n+m<k
ORDER BY(n-k)*m

Try it online

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

PHP, 65 bytes

for(;($n=$argn)!=$s.=$n[$i++];$b="$s
$b")$a.="$s
";echo"$a$n
$b";

Try it online!

Tests: Try it online!

In a loop creates a word with one letter added to it towards input on each iteration until the word has one letter less than the input.

For example if the input is "Hello" the word in first iteration is "H" and on third iteration is "Hel" and on last iteration is "Hell".

This word is appended to $a and prepended to $b with a newline. At the end $a, input, a newline and $b are printed.

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

C (clang), 56 52 bytes

i;f(*s,l){for(i=0;write(1,s,++i<l?i:l--);puts(""));}

Try it online!

-4 thanks to @ceilingcat

Takes a string and its length as arguments.

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

GolfScript, 27 bytes

.1/{0=1$?1$<}%n*.-1%@n+n\+\

Try it online!

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

Fortran (GFortran), 79 bytes

character(99)a
read*,a
k=len_trim(a)
print('(a)'),(a(1:k-abs(i-k)),i=0,2*k)
end

Try it online!

Fortran. Always good for string manipulation

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

Keg, 37 bytes

?1&((⑻|⑩")(⑻|')⑹
,)⑺⑺((⑻|⑩")(⑻|')⑺
,)

Try it online!

I decided to try an interesting string shifting approach.

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

.+?, 28 bytes

((.+).(\n.+)*)
\2\n\1\n\2
$

Thanks to JoKing for giving the original regex, which I then golfed a bit.

Explanation

((.+).(\n.+)*)  The full pattern
(            )  Makes group 1 the entire match, used in the replacement
 (.+).          Makes group 2 every character on the first line, except for the last character
      (\n.+)*   Makes it match the rest, so it all will get replaced

\2\n\1\n\2      Replacement
\2              Group 2 (first line except last character)
  \n            Newline
    \1          Group 1 (entire match)
      \n        Newline
        \2      Group 2 (first line except last character)

$               This match always fails. Makes the first pair repeat until it doesn't match, which happens when the first line has less than 2 characters.

Try it online! (The second command line argument is input)

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

Factor + grouping.extras, 38 bytes

[ head-clump dup reverse rest append ]

Try it online!

            ! "Hello"
head-clump  ! { "H" "He" "Hel" "Hell" "Hello" }
dup         ! { "H" "He" "Hel" "Hell" "Hello" } { "H" "He" "Hel" "Hell" "Hello" }
reverse     ! { "H" "He" "Hel" "Hell" "Hello" } { "Hello" "Hell" "Hel" "He" "H" }
rest        ! { "H" "He" "Hel" "Hell" "Hello" } { "Hell" "Hel" "He" "H" }
append      ! { "H" "He" "Hel" "Hell" "Hello" "Hell" "Hel" "He" "H" }
\$\endgroup\$
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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