Thanks to @KritixiLithos for helping me out with this challenge!

V is a programming language that I wrote so that I could use and extend vim for code-golf challenges. The very first commit was on March 3rd, 2016, meaning that today V turns one year old! Woo-hoo

Over V's first year of existence, there have been 176 commits from four different contributors, 140 answers from 12 different users, and too many broken duplicate operators to count. It has an online interpreter, generously hosted by @Dennis, which has been run almost 8,000 times since December.

Let's have a challenge to celebrate V's birthday! Since most features in V are designed with string manipulation and in mind, it just seems natural that any challenge celebrating V should be about ascii art. So your challenge for today is to take a word as input, and reshape that word in the shape of a V. For example, the input "Hello" should give the following V:

Hello         olleH
 Hello       olleH
  Hello     olleH
   Hello   olleH
    Hello olleH

Here are some details about what your V should look like. If the input string is n characters long, the V should be n*2 lines tall. The very first line should consist of:

<input string><(n*2) - 1 spaces><input string reversed>

On each new line, one space is added to the beginning, and the two sides of the string move towards each other, removing any overlapping characters. Until the very last line, which is just the first character of input. Trailing whitespace on each line is acceptable, and a trailing newline is allowed too.

You can assume that the input will always be printable ASCII without any whitespace in it, and you may take input and output in any reasonable method. Here are some more sample inputs:


Happy         yppaH
 Happy       yppaH
  Happy     yppaH
   Happy   yppaH
    Happy yppaH


Birthday               yadhtriB
 Birthday             yadhtriB
  Birthday           yadhtriB
   Birthday         yadhtriB
    Birthday       yadhtriB
     Birthday     yadhtriB
      Birthday   yadhtriB
       Birthday yadhtriB


V!   !V
 V! !V


~ ~

Of course, since this is , standard loopholes are banned and your goal is to write the shortest possible program to complete this task. Happy golfing!

For what it's worth, I have a soft spot for vim answers, so imaginary bonus points for using vim or V, although any language is acceptable. :)

  • \$\begingroup\$ Can I print a single null character (0x00) after every newline? \$\endgroup\$
    – Wheat Wizard
    Mar 3, 2017 at 0:24
  • \$\begingroup\$ @wheatwizard Hmm. It's a little weird, but I guess that's fine as long as the output is visually same. \$\endgroup\$
    – DJMcMayhem
    Mar 3, 2017 at 0:36
  • 22
    \$\begingroup\$ The 5th birthday will be something else! (In roman numerals) \$\endgroup\$ Mar 3, 2017 at 10:57
  • 5
    \$\begingroup\$ Best wishes to the V language by the Vee :-) \$\endgroup\$
    – The Vee
    Mar 6, 2017 at 9:46

44 Answers 44


PowerShell, 88 86 80 76 bytes

param($n)0..($l=$n.length*2-1)|%{-join((" "*$_+$n+" "*$l)[0..$l+($l-1)..0])}

Try it online!

Happy Birthday, V!

This takes the input $n, then we loop from 0 up to 2 * $length - 1. Each iteration, we slice into (pre-pended spaces + $n + appended spaces) from 0 up to the last character, and then back down to 0. That's -joined together into a string and left on the pipeline.

All those strings are gathered from the pipeline, and an implicit Write-Output happens at program completion with a newline in between elements.

Golfed 6 bytes by eliminating $b. Golfed another four by redoing $n calculations.


Perl 5, 58 + 1 (-n) = 59 bytes

$_.=$"x(($l=2*y///c)+3).reverse;say while s/(.{$l})../ $1/

Try it online!


Vyxal, 21 bytes


Try it Online!

This was interesting. Here's a bugged version.

Ld(                   # Length * 2 times do...
   n                  # Iteration number...
            ꘍         # Spaces, plus...
    ⁰                 # Input string...
          wi          # Sliced to first...
         ε            # Absolute difference of...
     n                # Iteration number...
         ε            # And...
        d             # Double...
      ⁰L              # The original string's length...
                ꘍     # Plus...
               -      # Difference of...
            ⁰L        # Original string's length
               -      # And...
              n       # Iteration number
                ꘍     # Spaces. 
                 øm   # Palindromised
                   ,  # And outputted. 

Mathematica (101 bytes)

Happy birthday to V from Mathematica!

Anonymous function, takes input as a string.

""<>NestList[" "<>StringDrop[#,{n,n+1}]&,#<>{" "~Table~{n=2StringLength@#-1},StringReverse@#,"

The newline is meant to be there.

Explanation: First, we generate the top line by joining the input, 2m-1 spaces (where m is the length of the input), the input reversed, and a newline. Then, each line is the previous one without the (2m-1)th and (2m)th characters, with a space added to the start.


Pyth, 22 bytes


     m              yl for d from 0 to double of length of input (exclusive)
                ;          space character
             *lQ           repeat as many times as length of input
           +Q              prepend input
       +*;d                prepend space repeated as many times as d
      <          ylQ       extract first (input length doubled) characters
 R                     for each string d obtained above
+                          append
  t_d                      tail of reverse of d (tail means d[1:])

Try it online! (a j is prepended to the code to make the output more beautiful)


Perl, 71 + 5 (-nlaF flag) = 76 bytes

Based on Dom Hastings solution.

push@F,($")x@F;print$"x$_,@F[0..$#F-$_],reverse@F[0..@F-$_-2]for 0..$#F

Try it online.

Perl, 81 + 5 (-nlaF flag) = 86 bytes

Previous version.

@F=(@s=(' ')x($l=@F*2),@F,@s);say@h=@F[-$_..$l-$_-1],reverse@h[0..@h-2]for-$l..-1

Try it online.

  • 1
    \$\begingroup\$ Hey, I made a slightly smaller version (81 bytes with print and same flags) It uses pretty much the same method as yours though: Try it online! \$\endgroup\$ Jul 7, 2017 at 12:07
  • \$\begingroup\$ @DomHastings -4 bytes. \$\endgroup\$ Jul 14, 2017 at 19:18
  • \$\begingroup\$ Amazing, good going! \$\endgroup\$ Jul 14, 2017 at 19:43

SmileBASIC, 131 127 125 109 105 91 85 84 bytes

Possibly some room for improvement here...

FOR I=1-K TO K?(" "*J+S$+" "*K)[K-ABS(I)];



The program uses k-ABS(x-k)-y (where k=length*2-1) to convert a position to a number:

 0 1 2 3 2 1 0
-1 0 1 2 1 0-1
-2-1 0 1 0-1-2
-3-2-1 0-1-2-3

To get rid of negative numbers, k is added:

3 4 5 6 5 4 3
2 3 4 5 4 3 2
1 2 3 4 3 2 1
0 1 2 3 2 1 0

Now we can just uses these as indexes into the input string, padded with k spaces on each end (...V!...).

V ! . . . ! V
. V ! . ! V .
. . V ! V . . 
. . . V . . .

Ruby, 70 bytes

I wasn't sure I could beat the other Ruby submissions, but I managed to do it. Those last three lines are killing me, though.

s+=" "*z+s.reverse
puts s
s=" "+s}}

Try it online!


Julia, 88 86 bytes

w=" ";a%b=b<w?a:a*b*(w*chop(a)%b[2:end]);!r=r[1:(n=end)]*w^n%(w^(n-1)*reverse(r)*"\n")


#Assign space char to w. 
w=" ";

#Redefine modulo operator so it is a V generator: 
#In the base case (when b is lexographically before a space, which
#occurs when b consists of a newline), print a.
#In the recursive case, concatenate a, b and the result to a recursive 
#call with arguments consisting of a shifted right, and b shifted 

#Frontend function for the V-generator, which automatically feeds the 
#V-generator with the correct arguments. 

Canvas, 8 bytes


Try it here!


l         push length of input
 «        multiply by 2
  *       push an array of the input repeated that many times
   \      pad with a space triangle
    l     push the height of that
     m    and mold the width to that, discarding anything after
      ││  palindromize horizontally

Charcoal, 23 bytes


Try it online!

This just draws lines downrightwards with the characters of the input and then reflect the canvas horizontally (skipping the central line). Verbose version here.

Charcoal, 26 bytes


Try it online!

This answer just draws consecutively smaller "V"-shaped polygons using the characters in the input. Verbose version here.

  • \$\begingroup\$ The requirement to mark newer languages/features as non-competing has recently been abolished. \$\endgroup\$ Jul 7, 2017 at 17:32
  • \$\begingroup\$ @ØrjanJohansen I didn't know it, thanks! \$\endgroup\$
    – Charlie
    Jul 7, 2017 at 18:01
  • \$\begingroup\$ You need to use ReflectOverlap because ReflectBufferfly switches bs and ds. I golfed @DLosc's solution down to 17 bytes using just features available at the time, but I can do it in 16 bytes now. \$\endgroup\$
    – Neil
    Sep 1, 2019 at 9:55

Stax, 10 bytes


Run and debug it


05AB1E, 11 bytes


Try it online!

ðs∍«η€ûR».C  # full program
         .C  # push centered lines of...
        »    # joined...
       R     # reversed list of...
     €û      # palindromized...
    η        # prefixes of...
  ∍          # length of...
 s           # implicit input...
ð            # spaces...
   «         # concatenated to...
             # implicit output...
        »    # by newlines
             # implicit output

Excel, 125 bytes

=LET(n,LEN(A1),y,SEQUENCE(1,4*n),z,2*n-ABS(2*n-y)+1-SEQUENCE(2*n),m,IF((z>0)*(z<=n),MID(A1,z,1)," "),CONCAT(IF(y=4*n,"

Try it online


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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