72
\$\begingroup\$

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
     HellolleH
      HellleH
       HeleH
        HeH
         H

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:

Happy         yppaH
 Happy       yppaH
  Happy     yppaH
   Happy   yppaH
    Happy yppaH
     HappyppaH
      HapppaH
       HapaH
        HaH
         H

Birthday:

Birthday               yadhtriB
 Birthday             yadhtriB
  Birthday           yadhtriB
   Birthday         yadhtriB
    Birthday       yadhtriB
     Birthday     yadhtriB
      Birthday   yadhtriB
       Birthday yadhtriB
        BirthdayadhtriB
         BirthdadhtriB
          BirthdhtriB
           BirthtriB
            BirtriB
             BiriB
              BiB
               B

V!:

V!   !V
 V! !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. :)

\$\endgroup\$
  • \$\begingroup\$ Can I print a single null character (0x00) after every newline? \$\endgroup\$ – Sriotchilism O'Zaic Mar 3 '17 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 '17 at 0:36
  • 21
    \$\begingroup\$ The 5th birthday will be something else! (In roman numerals) \$\endgroup\$ – Albert Renshaw Mar 3 '17 at 10:57
  • 5
    \$\begingroup\$ Best wishes to the V language by the Vee :-) \$\endgroup\$ – The Vee Mar 6 '17 at 9:46

40 Answers 40

2
\$\begingroup\$

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.

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

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

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

Try it online!

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

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@#,"
"},n]&

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.

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

Pyth, 22 bytes

+Rt_dm<+*;d+Q*lQ;ylQyl

     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)

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

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.

\$\endgroup\$
  • 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\$ – Dom Hastings Jul 7 '17 at 12:07
  • \$\begingroup\$ @DomHastings -4 bytes. \$\endgroup\$ – Denis Ibaev Jul 14 '17 at 19:18
  • \$\begingroup\$ Amazing, good going! \$\endgroup\$ – Dom Hastings Jul 14 '17 at 19:43
1
\$\begingroup\$

SmileBASIC, 131 127 125 109 105 91 85 84 bytes

Possibly some room for improvement here...

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

Explanation:

(Input=V!)

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 . . .
\$\endgroup\$
1
\$\begingroup\$

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.size*2-1
s+=" "*z+s.reverse
z.times{s[z,2]=""
puts s
s=" "+s}}

Try it online!

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

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

Explained:

#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 
#left.  
a%b=b<w?a:a*b*(w*chop(a)%b[2:end]);

#Frontend function for the V-generator, which automatically feeds the 
#V-generator with the correct arguments. 
!r=r[1:(n=end)]*w^n%(w^(n-1)*reverse(r)*"\n")
\$\endgroup\$
1
\$\begingroup\$

Canvas, 8 bytes

l«*\lm││

Try it here!

Explanation:

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
\$\endgroup\$
0
\$\begingroup\$

Charcoal, 23 bytes

AײLθαFθ«P↘…ια→A⁻α¹α»‖B

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

AײLθαFθ«GH>αιM⁻ײα³→A⁻α¹α

Try it online!

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

\$\endgroup\$
  • \$\begingroup\$ The requirement to mark newer languages/features as non-competing has recently been abolished. \$\endgroup\$ – Ørjan Johansen Jul 7 '17 at 17:32
  • \$\begingroup\$ @ØrjanJohansen I didn't know it, thanks! \$\endgroup\$ – Charlie Jul 7 '17 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 at 9:55

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.