20
\$\begingroup\$

Suppose an infinite tiling of hexagons composed of |/\ characters.

 / \ / \ / \ / \
|   |   |   |   |
 \ / \ / \ / \ /  etc.
  |   |   |   |
   \ / \ / \ /

Given input n > 0, output a triangular portion of that tiling as depicted in the below examples, anchored with a _ in the middle of a hexagon:

n=1
\_/

n=2
\/ \/
 \_/

n=3
\  |  /
 \/ \/
  \_/

n=4
\/ \ / \/
 \  |  /
  \/ \/
   \_/

n=5
\  |   |  /
 \/ \ / \/
  \  |  /
   \/ \/
    \_/

n=6
\/ \ / \ / \/
 \  |   |  /
  \/ \ / \/
   \  |  /
    \/ \/
     \_/

n=7
\  |   |   |  /
 \/ \ / \ / \/
  \  |   |  /
   \/ \ / \/
    \  |  /
     \/ \/
      \_/

n=8
\/ \ / \ / \ / \/
 \  |   |   |  /
  \/ \ / \ / \/
   \  |   |  /
    \/ \ / \/
     \  |  /
      \/ \/
       \_/

and so on

Rules

  • Leading/trailing newlines or other whitespace are optional, provided that the characters line up appropriately.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • Output can be to the console, saved as an image, returned as a list of strings, etc.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
\$\endgroup\$
  • \$\begingroup\$ If you count the number of end points along the top of the result, you get A029578 (the natural numbers interleaved with the even numbers) with an offset of 4. 2,4,3,6,4,8,5,10,6,12,7,14,... \$\endgroup\$ – Engineer Toast Oct 30 '17 at 14:40
  • \$\begingroup\$ What does "saved as an image" mean? is this tagged ascii-art? \$\endgroup\$ – tsh Oct 31 '17 at 5:28
  • \$\begingroup\$ @tsh For things like HyperCard or something, where output to a canvas is their equivalent of "stdout" output. I'm not picky on how the output is displayed. \$\endgroup\$ – AdmBorkBork Oct 31 '17 at 12:36

18 Answers 18

8
\$\begingroup\$

Python 2, 86 bytes

i=k=input()
while i:i-=1;print(" "*(k+~i)+"\\"+i*' /  |\  '[i%2::2])[:k-~i]+"_/"[i>0:]

Try it online!

One of Erik’s tricks allowed me to golf 3 bytes! Saved 3 bytes thanks to Jonathan Allan.

How this works

First off, this gets input from STDIN and assigns it to two separate variables i and k. Then, while the variable i is truthy, we decrement it and generate the strings accordingly; this is a shorthand for looping from the input - 1 all the way down to 0.

Generating the Strings

I'll split this into more parts:

  • First off, getting the leading spacing is achieved with " "*(k+~i). Since i is mapped through the range (input, 0], we must subtract it from k (our safely stored original input), decrement and repeat a space that many times.

  • +"\\" - Adds the character "\" to the spaces above.

  • ' / |\ '[i%2::2] - Generates our two strings, namely "/ \ " and " | ", in the following manner:

    • If i is odd, i % 2 is 1, thus [i%2::2] returns each 2 characters of our larger string, starting at index 1 (0-indexed).

    • If i is even, i % 2 is 1, thus the mechanism above does the same except it starts at index 0.

  • +~-i* - Repeats the string generated above, either "/ \ " or " | ", i-1 times, and appends it to the other strings. The benefit of the bitwise operator (~ - Bitwise Complement, Equivalent to i subtracted from -1) is that it doesn't require parenthesis in this context.

  • [:k-~i] - Gets all the characters of the strings concatenated above until index k-~i = k - (-1 - i) = k + 1 + i.

  • +"_/"[i>0:] - This only adds "/" if i ≥ 1, else it appends _/.

Full example / execution details

Let's grab an example of how things work for an input of 4:

i=k=input()        # i and k are assigned to 4.
while i:           # Starts the loop. The initial value of i is 4.
i-=1;              # Decrement i. i is now 3.
" "*(k+~i)         # A space repeated k - 1 - i = 4 - 1 - 3 = 0 times.
+"\\"              # Plus the character "\". CS (Current string): "\".
' /  |\  '[i%2::2] # The string ' /  |\  '[3%2::2] = ' /  |\  '[1::2] = "/ \ ".
i*                 # ^ repeated i = 3 times: "/ \ / \ / \ ".
+                  # And concatenate. CS: "\/ \ / \ / \ "
[:k-~i]            # Get the characters of ^ up to index k + 1 + i = 4 + 1 + 3 = 8.
                   # CS: "\/ \ / \".
+"_/"[i>0:]        # Append "_/"[i>0:] = "_/"[3>0:] = "_/"[1:] = "/".
                   # CS: "\/ \ / \/".
print              # Output the result "\/ \ / \/".
while i:           # i is truthy (> 0), thus we loop again.
i-=1;              # Decrement i. i becomes 2.
" "*(k+~i)         # " " repeated 4 - 2 - 1 = 1 time. 
+"\\"              # Plus "\". CS: " \".
' /  |\  '[i%2::2] # ' /  |\  '[2%2::2] = ' /  |\  '[::2] = "  | ".
+i*                # Repeat i = 2 times and append: "  | ". CS: " \  |  |".
[:k-~i]            # CS up until k + 1 + i = 4 + 2 + 1 = 7. CS: " \  |  ".
+"_/"[i>0:]        # Append "/". CS: " \  |  /".
print              # Outputs the CS: " \  |  /".
while i:           # i is truthy (> 0), thus we loop again.
i-=1;              # Decrement i. i is now 1.
" "*(k+~i)         # " " repeated 4 - 1 - 1 = 2 times. 
+"\\"              # Plus "\". CS: "  \".
' /  |\  '[i%2::2] # ' /  |\  '[2%2::2] = ' /  |\  '[::2] = "/ \ ".
+i*                # Repeat i = 1 time and append: "/ \ ". CS: "  \/ \ ".
[:k-~i]            # CS up until k + i + 1 = 4 + 2 = 6. CS: "  \/ \".
+"_/"[i>0:]        # Append "/". CS: "  \/ \/".
print              # Outputs the CS: "  \/ \/".
while i:           # i is truthy (> 0), thus we loop again.
i-=1;              # Decrement i. i is now 0.
" "*(k+~i)         # " " repeated 4 - 1 - 0 = 3 times. 
+"\\"              # Plus "\". CS: "   \".
' /  |\  '[i%2::2] # ' /  |\  '[1%2::2] = ' /  |\  '[1::2] = "  | ".
+i*                # Repeat i = 0 times and append: "   \". CS: "   \".
[:k-~i]            # CS up until k + i + 1 = 4 + 0 + 1 = 5. CS: "   \".
+"_/"[i>0:]        # Append "_/" (because i > 0 is False since i == 0). CS: "  \_/".
print              # Outputs the CS: "  \_/".
while i:           # i == 0, hence the condition is falsy and the loop ends. 
                   # Program terminates.
\$\endgroup\$
  • \$\begingroup\$ Move the i-=1 to the start of the loop and use a slightly different right-hand-side formation to get it down to 87 bytes. \$\endgroup\$ – Jonathan Allan Oct 30 '17 at 20:09
  • \$\begingroup\$ ...in fact even better at 86 bytes using something like your right-hand-side formation :) \$\endgroup\$ – Jonathan Allan Oct 30 '17 at 20:15
  • \$\begingroup\$ @JonathanAllan ... Thanks! (Although redoing the explanation will be... tough!... sigh) \$\endgroup\$ – Mr. Xcoder Oct 30 '17 at 20:22
  • \$\begingroup\$ @JonathanAllan I found an alternative that does not reverse the order of the decrement statement. \$\endgroup\$ – Mr. Xcoder Oct 30 '17 at 21:24
4
\$\begingroup\$

Python 2, 90 bytes

n=N=input()
while N:print' '*(n-N)+'\\'+(('/   \|  '[N%2::2]*n)[:N*2-1],'_')[N<2]+'/';N-=1

Try it online!

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

05AB1E, 33 bytes

1ŸεÐi'_ë"/ \   | "4ôsès∍}'\ì.∞}.c

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Try it online! - Tried exploiting the "0300" and "2010" pattern, didn't go so hot. \$\endgroup\$ – Magic Octopus Urn Nov 10 '17 at 1:50
  • \$\begingroup\$ @MagicOctopusUrn That doesn't print an underscore too :p \$\endgroup\$ – Erik the Outgolfer Nov 10 '17 at 9:10
2
\$\begingroup\$

Mathematica, 131 bytes

Join[Table[s=StringRiffle@Table[If[OddQ@i,"/ \\"," | "],⌈i/2⌉];""<>{"\\",If[!OddQ@i,{" ",s," "},s],"/"},{i,#-1,1,-1}],{"\_/"}]&   


returns a list of strings

Try it online!

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

Retina, 129 119 112 bytes

\d+
$* 
 
¶$`a $'$' 
m`$
/
  /$
_/
^.¶

a(    )*/
a$#1/
\d+
$*
1
/ a  
 (    )*/
$#1/
\d+
$*
1
 |  
a /¶
a/¶
a
\

Try it online!

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

Charcoal, 26 bytes

NθG↖→↓θ“ ″✂=AL«Q"η\`”←_↖θ‖B

Try it online! Link is to verbose version of code.

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

Python 2, 123 112 110 109 100 98 96 bytes

i=n=input()
while i:a=i%2;print' '*(n-i)+'\%s/'%['_',((-~i/2)*'/   \  |'[a::2])[a:~a]][i>1];i-=1

Try it online!

  • Saved a bunch of bytes by using input and string formatting as in Rod's answer
  • Saved 2 bytes thanks to Mr. Xcoder
\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 2 bytes by replacing -1-a with ~a (as I did in my answer). \$\endgroup\$ – Mr. Xcoder Oct 30 '17 at 14:41
  • \$\begingroup\$ @Mr.Xcoder Thanks :) \$\endgroup\$ – TFeld Oct 30 '17 at 18:47
1
\$\begingroup\$

Python 2, 103 bytes

i=n=input()
while i:print' '*(n-i)+'\%s/'%' '.join(['/\\'*(-~i/2),['_',' '+'| '*(i/2)][i>1]][i%2]);i-=1

Try it online!

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

APL (Dyalog), 97 93 bytes

{⍵=1:1 3⍴'\_/'⋄x←' ',' ',⍨∇⍵-1⋄y←1+2×⍵-1⋄2|⍵:x⍪⍨'\','/',⍨y⍴'  | '⋄x⍪⍨'\/','\/',⍨(y-2)⍴' \ /'}

Try it online!

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

SOGL V0.12, 28 27 bytes

╔.H∫"C↕‽«‘4nwιF«Im}¹⌡¾\/¹№╚

Try it Here!

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

Haskell, 96 95 bytes

f n=[([1..n-x]>>" ")++'\\':take(2*x+1)(cycle$("_":a)!!x)++"/"|x<-[n,n-1..0]]
a="/ \\ ":"  | ":a

Try it online!

0-indexed and returns a list of lines.

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

Haskell, 101 99 bytes

j 1=["\\_/"]
j n|r<-([1,3..n-1]>>)=('\\':cycle[init$r"/ \\ ",' ':r" |  "]!!n++"/"):map(' ':)(j$n-1)

Returns a list of lines.

Try it online!

How it works:

j 1=["\\_/"]               -- base case, n=1

j n                        -- for all other n
   |r<-([1,3..n-1]>>)      -- let r be the function that makes n/2 copies of
                           -- it's argument
   =                       -- the result is
      '\\':                --  a backslash, followed by
      cycle[  ]!!n         --  the inner part, which is
          init$r"/ \\ "    --    all but the last char of some copies of
                           --    "/ \ " for even line numbers, or
          ' ':r" |  "      --    some copies of " |  " prepended by a space
                           --    for odd line numbers
                           --    (chosen by indexing an infinite list of
                           --     both values alternating)   
      ++"/"                --  followed by a slash
    :                      --  and append a
               j$n-1        --  recursive call with n-1
      map(' ':)            --  where each line is prepended by a space

Edit: @Laikoni saved two bytes. Thanks!

\$\endgroup\$
  • \$\begingroup\$ ([1,3..n-1]>>) can be used instead of ([1..div n 2]>>) . \$\endgroup\$ – Laikoni Oct 30 '17 at 15:53
0
\$\begingroup\$

Java (OpenJDK 8), 315 306 bytes

i->{String r="";int j=0,k,u=i*2;char[][]c=new char[i][u+1];c[i-1][i]=95;for(;j<i;r+="".valueOf(c[j++]).replace('\0',' ')+"\n")for(k=0;k<u+1;k++){if(k==j)c[j][k]=92;if(k==u-j)c[j][k]=47;if(k>j&k<u-j)if((i-j)%2<1)c[j][k]=(k-j-1)%2<1?(char)(47+((k-j-1)/2)%2*45):32;else if((k-j-1)%4==2)c[j][k]='|';}return r;}

Try it online!

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

Java (OpenJDK 8), 198 bytes

Finally got it below 200 bytes. Will probably post an explanation later.

i->{for(int k=i+1;i>0;System.out.println(("".format("%"+(k-i)+"s","")+"\\"+(i<2?"":"".format("%"+(i-1)+"s","")).replace(" ","/ \\ ,  | ".split(",")[i%2])).substring(0,i<2?k:k+i)+(--i<1?"_/":"/")));}

Try it online!

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

JavaScript (ES6), 89 85 bytes

f=(y,s='\\')=>--y?s+(y&1?' / \\':' |  ').repeat(y).slice(~y-y)+`/
`+f(y,' '+s):s+'_/'

Demo

f=(y,s='\\')=>--y?s+(y&1?' / \\':' |  ').repeat(y).slice(~y-y)+`/
`+f(y,' '+s):s+'_/'

console.log(f(1))
console.log(f(2))
console.log(f(3))
console.log(f(4))
console.log(f(5))
console.log(f(6))
console.log(f(7))

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

CJam, 43

ri_{S*'\@(:X"  | / \ "4/=X*X2*)<'_e|'/NX}/;

Try it online

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

PHP, 89+1 bytes

while($k=$argn-$n)echo($p=str_pad)("",$n++),$p("\\",2*$k,$k>1?$k&1?"  | ":"/ \ ":_),"/
";

Run as pipe with -nR or try it online.

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

Pyth,  46  44 bytes

j_m+<++*;t-Qd\\*d%2>" /  |\  "%d2h+Qd>"_/"._

Try it here!

\$\endgroup\$

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.