g | x | w | all
Bytes Lang Time Link
005Vyxal 3250215T004046Zmoon-bot
009Uiua240423T205606Znoodle p
058AWK241202T212952Zxrs
038Wolfram Language Mathematica190902T092720Zatt
126Gray Snail240426T230248ZDLosc
108Rust240423T192033ZDornteuf
038Factor + grouping.extras220625T013158Zchunes
002Vyxal j220625T012128ZnaffetS
063Python 3220111T170340Zpython-b
064JavaScript ES6220112T171437ZMerlin04
096Python 3.8 prerelease220110T171424ZLarry Ba
041Knight210616T062444ZSampersa
033x8616 machine code210616T020146ZEasyasPi
043Ly210615T080806Zcnamejj
003Vyxal j210615T064857Zemanresu
032Branch210419T044428Zhyperneu
003Canvas210419T041452ZRazetime
041Scala201103T094937ZTomer Sh
063Python 2190228T071221ZElPedro
106Java JDK201103T104620ZConffusi
nanx8616 machine code190301T213339Z640KB
028.+?200220T190442ZEdgex42
037Keg200120T222015Zlyxal
079Fortran GFortran200120T173257ZDeathInc
027GolfScript200120T130118Zuser8505
00305AB1E legacy190227T105420ZKevin Cr
072Python 3191031T012859ZCello Co
052C clang190902T100649Zatt
254BrainFlak190904T090420ZDorian
029CJam190902T085633ZEdgex42
052Python 2190901T210736ZChas Bro
060Zsh190901T210719ZGammaFun
078C190324T174419ZYoris
065PHP190831T101653ZNight2
003Gaia190404T220448ZGiuseppe
119TSQL query190404T203005Zt-clause
010Pyth190404T044915ZGammaGam
031Perl 6190227T110217ZJo King
006Husk190320T060124ZUnrelate
091Java 8190308T223807ZBenjamin
143SAP ABAP Unicode190315T223510ZMaz
nanHaskell190227T205121ZJoseph S
058C gcc190228T134457Zgastropn
059C gcc190227T104246Zbuttercr
032[Assembly nasm190302T220106Zmoonhear
037Röda190302T091920Zfergusq
072BASH + GNU coreutils190306T153921ZRene
053x86 machine code Linux190305T203504Zuser3604
090Python 2190228T170034Zakozi
nan190228T164228ZChronoci
091JavaScript Node.js190302T105449ZKamil Na
004Japt R190227T144058ZQuintec
079PHP190301T184330Z640KB
076Nim190301T153030Zaloisdg
100Wolfram Language Mathematica190301T133107ZRainer G
077Factor190301T120815ZGalen Iv
036JavaScript ES6190227T104628ZArnauld
012J190227T113122ZGalen Iv
048Python 3.8 prerelease190227T153325Zxnor
063Wolfram Language Mathematica190301T041010ZKai
011J190227T114340ZAdá
048APLNARS190228T183650Zuser5898
062Kotlin190228T200803Zsnail_
035sed190228T005505ZSophia L
040Julia190227T133408ZDoorknob
004Jelly190227T153414ZConor O&
086Java JDK190228T123239ZOlivier
041><>190228T114422ZEmigna
007MathGolf190228T113512Zmaxb
058R190227T154949ZCriminal
032brainfuck190227T191808ZNitrodon
046PowerShell190228T043040Zmazzy
036Haskell190228T050703Zxnor
061F# .NET Core190227T222008Zaloisdg
081C# Visual C# Interactive Compiler190227T145915Zaloisdg
007Japt R190227T103254ZASCII-on
076C# Visual C# Interactive Compiler190227T212036Zdana
031APL+WIN190227T193154ZGraham
006Brachylog v2190227T173554Zais523
118SNOBOL4 CSNOBOL4190227T161131ZGiuseppe
015Attache190227T153556ZConor O&
006Pyke190227T150252ZBlue
103MBASIC190227T142445Zwooshiny
090JavaScript Node.js190227T142346ZT. Dirks
086R190227T141326ZSumner18
008Brachylog190227T140544ZFatalize
078Red190227T115529ZGalen Iv
058Octave190227T140154ZLuis Men
040Ruby190227T104440ZKirill L
074C# Visual C# Interactive Compiler190227T111231Zthe defa
008MATL190227T121953ZSanchise
026Perl 5 p190227T120024ZNahuel F
005Charcoal190227T115233ZNeil
009APL Dyalog Unicode190227T114612ZAdá
052Python 2190227T104034ZTFeld

Vyxal 3, 5 bytes

-1 byte by lyxal

PæᐕJ”

Somehow longer than the vyxal2 answer because no palindromize :/

PæᐕJ”­⁡​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌­
P       # ‎⁡prefixes
 æ      # ‎⁢bifurcate : copy and reverse
   ᐕ    # ‎⁣behead
    J”  # ‎⁤concat the 2 copies, join on newlines
💎

Created with the help of Luminespire.

I am a bot created by Themoonisacheese, please feed me butter.

Vyxal It Online!

Uiua, 13 9 bytes

˜⊂↘1⊸⇌⧅□

Try it!

Outputs a list of boxed lines.

Explanation: Take the prefixes of the string, and append a reversed copy with the first removed.

AWK, 58 bytes

{for(l=length;i++<l*2;)print substr($0,1,i<=l?i:i-(x+=2))}

Attempt This Online!

{for(l=length;i++<l*2;) # twice as many lines as chars
print substr($0,1,      # print from beginning of string
i<=l?i:i-(x+=2))}       # first or second half

Wolfram Language (Mathematica), 39 38 bytes

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

Try it online!

Input a list of characters. Return a list of character lists.

Gray Snail, 126 bytes

INPUT s
POP n a "
"
POP  z 
L
POP c s [s]
POP _  _[][c]
GOTO   [s]
POP _ a _[a][][n]
POP _ z _[n][][z]
GOTO L

OUTPUT [a][][z]

Try it here! (Paste the code, then click Compile Code, then click Execute Program, then enter your input and click Set Input.)

Ungolfed, with comments

INPUT instring
"Set nl to newline character and front to empty string"
POP nl front "
"
"Set both partial and back to empty string"
POP partial back ""

#loop
"Pop the first character from instring and store it in char"
POP char instring [instring]
"Set partial to partial + char"
POP _ partial _[partial][char]
"If instring is now empty, exit the loop"
GOTO #endloop "" [instring]
"Set front to front + partial + nl"
POP _ front _[front][partial][nl]
"Set back to nl + partial + back"
POP _ back _[nl][partial][back]
GOTO #loop

#endloop
"Concatenate and output front + partial + back
 (Note that partial now contains the full original string)"
OUTPUT [front][partial][back]

Rust, 108 bytes

|a:&str|for i in(1..=a.len()).chain((1..a.len()).rev()){print!("{}
",a.chars().take(i).collect::<String>())}

Attempt This Online!

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" }

Vyxal j, 2 bytes

¦∞

Try it Online!

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!

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)

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!

Knight, 41 bytes

;=aP;=nF;W<=n+1nLaO GaFn;OaW=aSa-LaT1""Oa

Nothing too fancy, we just print out the first half, then the middle, then the second.

; = a PROMPT # read stdin
; = n FALSE # will coerce to `0` within the `WHILE` condition, but saves us a space from `=n 0`

# until we're at the length of `a`, print the prefix [0..n] from `a`
; WHILE < (=n + 1 n) (LENGTH a)
    OUTPUT (GET a FALSE n)

# output the entire thing
; OUTPUT a

# continue removing pieces from the end of `a` until it's empty, and printing `a` in the process
WHILE (= a SUBS a (- LENGTH a TRUE) 1 "")
    OUPUT a

x86-16 machine code, IBM PC-DOS, 33 bytes

Hexdump:

00000000: bf 82 00 91 89 fa e8 0a 00 74 06 41 eb f8 e8 02  .........t.A....
00000010: 00 e2 fb b4 40 cd 21 b0 0d ae cd 29 b0 0a cd 29  ....@.!....)...)
00000020: c3                                               .

Commented assembly:

        [org 0x100]
start:
        ; DI <- first command line argument
        mov     di, 0x0082
        ; DOS startup state abuse 1: set CX to zero by swapping AX (0x0000)
        xchg    cx, ax
        ; DX <- DI
        mov     dx, di
.loop1:
        ; A multitasking loop.
        ; This both prints the string up to the full length and counts
        ; the chars by scanning for '\r'.

        ; Print DS:DX(CX)
        ; We test for the end of string when printing
        ; the newline by using SCASB.
        call    putsn
        ; If the SCASB returned true, break to the end of .loop2
        ; We don't go to the top because it would print the full
        ; length string twice.
        jz      .next
        ; Increment the length and character counter
        inc     cx
        ; Loop to loop1
        jmp     .loop1
        
.loop2: ; Shortening loop
        ; Print
        call    putsn
.next:
        ; while (--CX)
        loop    .loop2
        ; Fallthrough: prints an empty line (as CX is 0) and exits

        ; Prints CX chars from DX, followed by a newline.
putsn:
        ; DOS startup state abuse 2: BX is 0x0000.
        ; DOS lets you write to STDIN and it still prints to the screen.
        ; Why? I have no idea. It's very convenient though. Note that
        ; this behavior is consistent on DOS 6.22 and FreeDOS 1.3rc4.
        ;
        ; write(0, argv, CX)
        mov     ah, 0x40
        int     0x21
        ; Print \r\n with INT 29h
        mov     al, 13
        ; Since we have \r in AL, we can use SCASB to check
        ; for the end of the string when we return.
        ; Interrupts save the flags.
        ;
        ; Yes, this reads out of bounds on the second loop,
        ; but it is DOS, who cares?
        scasb
        int     0x29
        mov     al, 10
        int     0x29
        ret

To be even with 640KB, I also used the command line arguments, but I made some changes:

  1. I use write (21:40) instead of puts (21:09). While it does require manually printing a newline, it lets me manually control the length just by changing CX.
  2. I count the length of the command line arguments on the fly.
  3. I did some other tricks.

This abuses the newline rule: it actually prints empty strings at the start and end.

What did you expect?

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
     

Vyxal j, 3 bytes

¦øm

Try it Online!

-3 thanks to lyxal

¦   # Prefixes
 øm # Palindromised
    # Joined by newlines

Branch, 32 bytes

,[[^]/[./]10.,]^[0^[^]/[./]10.^]

Try it on the online Branch interpreter!

Explanation

,                 Read a character from STDIN
[            ]    While true (while input is not EOF)
 [^]              Keep going up until we hit 0; this is the parent of the first input node
    /             Go to the input node
     [./]         While true, output the node and descend; outputs all input at this point
         10.      Output 10 (newline)
            ,     Read the next character
^                 Go up one space (this puts us on the last input node)
[              ]  While true (while we haven't deleted all of the input yet)
 0^               Zero the current value and go up (delete the last character)
   [^]/           Go to the top again
       [./]       Output all of the input again (gradually gets deleted)
           10.    Output newline
              ^   Go up again; this is the new last input character

This can actually be ported quite easily.

brainf***, 56 bytes

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

Try it online!

Basically does the same thing as above. However, BF can't set the value of a cell like Branch can, so instead we can zero with [-] (which doesn't actually work well in Branch because long long int can take a long long time to zero if its initial value is -1) and then to get 10, we can just do + 10 times after zeroing.

Canvas, 3 bytes

[]─

Try it here!

Scala, 41 bytes

s=>s.inits.toSeq.reverse++s.inits.drop(1)

Try it online!

Scala, 61 57 bytes

s=>1.to(2*s.size-1).map(x=>s.take(s.size-(s.size-x).abs))

Try it online!

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.

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

x86-16 machine code, IBM PC DOS,  44  43 39 bytes

00000000: d1ee ad8b d648 93b7 248a cbd0 e13a d975  .....H..$....:.|
00000010: 01fd ac86 3cb4 09cd 2186 3cb8 0d0e cd10  ....<...!.<.....
00000020: b00a cd10 e2e7 c3                        .......

Build and test YT.COM using xxd -r from above.

Unassembled:

D1 EE       SHR  SI, 1              ; point SI to DOS PSP at 80H (SI intialized at 100H) 
AD          LODSW                   ; load input length into AL, SI = 82H 
8B D6       MOV  DX, SI             ; save start of string pointer 
48          DEC  AX                 ; remove leading space from string length 
93          XCHG AX, BX             ; save string length in BL
B7 24       MOV  BH, '$'            ; put end-of-string marker in BH
8A CB       MOV  CL, BL             ; set up loop counter in CL
D0 E1       SHL  CL, 1              ; number of lines = 2 * string length - 1
    LINE_LOOP:
3A D9       CMP  BL, CL             ; does CL = string length?
75 01       JNZ  LINE_OUT           ; if not, go to output line
FD          STD                     ; otherwise flip DF to descend
    LINE_OUT: 
AC          LODSB                   ; increment or decrement SI
86 3C       XCHG BH, [SI]           ; swap current string byte with end of string delimiter 
B4 09       MOV  AH, 9              ; DOS API display string function 
CD 21       INT  21H                ; write substring to console 
86 3C       XCHG BH, [SI]           ; restore string byte 
B8 0E0D     MOV  AX, 0E0DH          ; AH = 0EH (BIOS tty function), AL = CR char
CD 10       INT  10H                ; write CR to console
B0 0A       MOV  AL, 0AH            ; AL = LF char
CD 10       INT  10H                ; write LF to console
E2 E6       LOOP LINE_LOOP          ; move to next line 
C3          RET                     ; return to DOS

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.

Standalone PC DOS executable program, takes input string from command line.

Output

enter image description here

.+?, 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)

Keg, 37 bytes

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

Try it online!

I decided to try an interesting string shifting approach.

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

GolfScript, 27 bytes

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

Try it online!

05AB1E (legacy),  4  3 bytes

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

η.∊

Try it online or verify all test cases.

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.


3 bytes alternative provided by @Grimy:

ηû»

This version works in both the legacy and new version of 05AB1E.

Try it online (legacy), try it online (new version) or verify all test cases (new version).

Explanation:

η     # Get all prefixed of the (implicit) input-string
 û    # Palindromize each string in this list
  »   # And then join the list of strings by newlines
      # (after which the result is output implicitly)

Python 3, 79 72 bytes

Thanks Jo King for helping me save 7 bytes

I'm a bit late to this golf, but I was bored and didn't see a Python 3 one that gave a printable string and not a list. This isn't exactly very short but this is my first code golf post :)

lambda x:'\n'.join(x[:[i,len(x)-i][i>len(x)]]for i in range(1,len(x)*2))

Try it online!

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.

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

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!

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.

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

C, 78 bytes

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

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.

Gaia, 3 bytes

…ṫṣ

Try it online!

As simple as it gets.

…	| prefixes
 ṫ	| palindromize
  ṣ	| join with newlines

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

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!

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

Husk, 6 bytes

S+o↔hḣ

Try it online!

Takes input as an argument.

S      Apply the first argument to the third argument and to the second argument applied to the third argument:
 +     concatenation,
 o     the composition of
  ↔    reversal
  h    with removal of the last element,
 ḣ     every prefix of
       the input.

...I may need to not try to explain combinators in plain English.

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

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

Haskell, 52 50 44 bytes

f x=unlines$init<>reverse$scanr(\_->init)x x

Try it online!

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!

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!

[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!

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 */
 ]
}

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

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!

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!

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

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!

Japt -R, 4 bytes

å+ ê

Cumulative reduce on a string.

-1 byte thanks to @Shaggy

Try it online!

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!

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.

Wolfram Language (Mathematica), 100 bytes

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

Try it online!

Factor, 77 bytes

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

Try it online!

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

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!

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!

Wolfram Language (Mathematica), 63 bytes

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

Try it online!

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

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[⍵]}

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!

sed, 31 35 bytes

:x
h
s/.\n.*\|.$//
/^$/{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                 

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.

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.

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!

><>,  44  41 bytes

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

Try it online!

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

R, 79 65 62 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.

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
]

PowerShell, 46 bytes

($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!

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!

F# (.NET Core), 67 61 bytes

let l=s.Length
[1..l*2-1]|>Seq.map(fun i->s.[..l-abs(i-l)-1])

Try it online!

Input is a string and output is a seq<string>

Another solution could be let f(s:string)=for i=1 to s.Length*2-1 do printfn"%s"s.[..s.Length-abs(i-s.Length)-1] for 80ish bytes... I am not sure that it is worth looking into.

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

Japt -R, 9 7 bytes

-2 bytes thanks to Shaggy

Êõ@¯XÃê

Try it online!

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

APL+WIN, 31 bytes

Prompts for input of string:

 ⊃((⍳n),1↓⌽⍳n)↑¨(¯1+2×n←⍴s)⍴⊂s←⎕

Explanation:

(¯1+2×n←⍴s)⍴⊂s create a nested vector of the string of length =1+2x length of string

((⍳n),1↓⌽⍳n)↑¨ progressively select elements from each element of the nested vector 
              following the pattern 1  2 ...to n to n-1 ... 1

⊃ convert nested vector into a 2d array.

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.

SNOBOL4 (CSNOBOL4), 118 bytes

	N =INPUT
	L =1
1	X =LT(X,SIZE(N)) X + 1	:F(D)
O	N ARB . OUTPUT POS(X)	:($L)
D	X =GT(X) X - 1	:F(END)
	L ='D'	:(O)
END

Try it online!

There appears to be a bug in this implementation of SNOBOL; attempting to replace the label D with the label 2 causes an error, although the manual for Vanilla SNOBOL indicates that (emphasis added)

If a label is present, it must begin with the first character of the line. Labels provide a name for the statement, and serve as the target for transfer of control from the GOTO field of any statement. Labels must begin with a letter or digit, optionally followed by an arbitrary string of characters. The label field is terminated by the character blank, tab, or semicolon. If the first character of a line is blank or tab, the label field is absent.

My supposition is that the CSNOBOL interpreter only supports a single label that begins with an integer.

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.

Pyke, 6 bytes

BE 27 4F 5F 2B 58

Try it here!

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

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

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!

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.

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)

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!

Octave, 58 bytes

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

Try it online!

Ruby, 51 42 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.

C# (Visual C# Interactive Compiler), 123 109 94 84 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!

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

Perl 5 (-p), 26 bytes

s,.,$\=$`.$/.$\;"$`$&
",ge

TIO

Charcoal, 5 bytes

G^Lθθ

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), Lθ specifies the length of those sides as being the length of the original input and the final θ specifies the fill string.

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

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!