# Triangles of Hexagons

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.
• 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,... – Engineer Toast Oct 30 '17 at 14:40
• What does "saved as an image" mean? is this tagged ascii-art? – tsh Oct 31 '17 at 5:28
• @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. – AdmBorkBork Oct 31 '17 at 12:36

# 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.

• 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. – Jonathan Allan Oct 30 '17 at 20:09
• ...in fact even better at 86 bytes using something like your right-hand-side formation :) – Jonathan Allan Oct 30 '17 at 20:15
• @JonathanAllan ... Thanks! (Although redoing the explanation will be... tough!... sigh) – Mr. Xcoder Oct 30 '17 at 20:22
• @JonathanAllan I found an alternative that does not reverse the order of the decrement statement. – Mr. Xcoder Oct 30 '17 at 21:24

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

# 05AB1E, 33 bytes

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


Try it online!

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

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

# Retina, 129119 112 bytes

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

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


Try it online!

# Charcoal, 26 bytes

ＮθＧ↖→↓θ“ ″✂=ＡＬ«Q"η\”←_↖θ‖Ｂ


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

# Python 2, 12311211010910098 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
• You can save 2 bytes by replacing -1-a with ~a (as I did in my answer). – Mr. Xcoder Oct 30 '17 at 14:41
• @Mr.Xcoder Thanks :) – TFeld Oct 30 '17 at 18:47

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

# APL (Dyalog), 97 93 bytes

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


Try it online!

# SOGL V0.12, 28 27 bytes

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


Try it Here!

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. ## 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! • ([1,3..n-1]>>) can be used instead of ([1..div n 2]>>) . – Laikoni Oct 30 '17 at 15:53 # 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! # 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! # 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)) # CJam, 43 ri_{S*'\@(:X" | / \ "4/=X*X2*)<'_e|'/NX}/;  Try it online # 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.

# Pyth,  46  44 bytes

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

Try it here!