# Draw an ASCII hexagon of side length n

Given a positive integer $$\n$/extract_tex] output an ASCII hexagon with diagonal side length $$\n$$/extract_tex], as pictured (note there are $$\2n\$$ _ characters on the top edge) ### Examples: $$\n = 1\$$  __ / \ \__/  $$\n = 2\$$  ____ / \ / \ \ / \____/  $$\n = 5\$$  __________ / \ / \ / \ / \ / \ \ / \ / \ / \ / \__________/  etc. Shortest code in bytes wins. Usual input/output methods apply. • Does this answer your question? Draw Concentric ASCII Hexagons Jan 6 at 7:59 • Related, Related, Related, Related. Apparently we didn't have this exact challenge so far, which is the GCD(?) of all. Jan 6 at 8:02 • @pxeger No, I had already seen that question. I expect this code should be more concise, for the simpler requirements. – wim Jan 6 at 8:15 • I don't think this is a dupe of the concentric hexagons question. Nested ASCII art is much more difficult to do programmatically even if it is trivial for humans. However I would be happy to see this closed as a duplicate of any one of the dozens of "scale up this ascii art" challenges we have, as this offers nothing new or interesting to a far overdone category of challenges. I won't cast my vote though because it is binding. Jan 6 at 8:33 • I think it's nice to have this as a hexagon-drawing challenge in its simplest form. – xnor Jan 6 at 9:46 ## 22 Answers # Canvas, 15 9 bytes  _；１＊⁸／∔╬  -6 bytes after fixing the program. Draws a quarter of the hexagon, and quad palindromizes. # Python 2, 92 bytes k=n=input() while 1:a=k^k>>n;print" "*a+"\/_"[k/n-2]+"_ "[-n<k<n]*2*(2*n+~a)+"\_/"[k/n];k-=1  Try it online! • I love how the k/n-2 serves a dual purpose to avoid escaping the backslash and also to force an error to avoid having a while loop condition. Jan 6 at 10:45 • I am not a regular on codegold SE, is unhandled exception / stderr traceback generally allowed? while k>~n: is still pretty competitive. – wim Jan 6 at 16:10 • @wim As the challenge author, you are free to disallow exiting with an error, but, by default, it is allowed Jan 6 at 18:11 # C (gcc), 119 109 bytes a,i,j;f(n){for(i=a+=a=j=n*2;~j;)putchar(!i--?i=a,j--,13:i%(n*3)<n|j%(n*2)?(i-~j-n)%a?(i-j+n)%a?32:92:47:95);}  Try it online! • saved 2 thanks to @ceilingcat The table below is not updated so values can differ, but the concept is: • we have 2 pairs of parallel lines  . . _______.______.________ | / \ | . . | / \ | . .| / \ |. |/ \| |\ /|. .| \ / | . . | \ / | __|___\________/___|___ | . .  we iterate x,y from size to 0 and we sum them to check if a / should be printed, we subtract to check for \ , we use modulo to check both parallels.  i 65432109876543210. j i+j-n ________ 8 13+7-4=> / \ 7 14+6-4 / \ 6 15+5-4 / \ 5 / \ 4 \ 1+3-4=> / 3 \ 2+2-4 / 2 \ 3+1-4 / 1 \________/ 0  • Woah! I had a draft for this question, but there is no comparison, your approach is unbeatable. Jan 13 at 21:09 • @Davide thank you so much for appreciation! I really love to see that C is still interesting and I think golfing it has its own funny things no other languages can offer despite its weakness on more complicated algorithms Jan 13 at 22:34 # Charcoal, 14 bytes ←×_θ↖θ→↗θ×_θ‖Ｍ  Try it online! +1 byte fix from ASCII-Only. Draws half of the hexagon, and mirrors it. • nice broken link :/ Jan 6 at 9:09 • also doesn't work; horizontal lines in charcoal use - not _ Jan 6 at 9:12 • fixed, 17 Jan 6 at 9:14 • 14 Jan 6 at 9:21 • none of the examples use hyphens. also --ppcg worked for me so idk what you did Jan 6 at 9:38 # Haskell, 100 bytes f n=unlines[q<>[1..3*n]++[1-n..0]|y<-[-n..n],let q x|abs y==n,x>n='_'|x==y='\\'|x+y==1='/'|1>0=' ']  Try it online! Golfing AZTECCO's answer plus some new techniques. The main idea is that the hexagon is simpler if we transplant the first n columns to the end. |-| ______ / \ / \ / \ \ / \ / \______/ |-| ______ \ / \ / \/ /\ / \ ______/ \  Now all the / and \ are in a single line, and the _ are all to the left of those. This makes it much easier to do AZTECCO's strategy of determining the character from the coordinate. To implement these relabeled coordinates, we replace the x-coordinates [1..4*n] with a cycled and shifted version [1..3*n]++[1-n..0]. • this is great! That way you avoid the modulo operations! Thanks for the help btw , I think I'm gonna leave mine as it is to stick to my primitive approach, maybe I'll try to use yours in my C answer instead Jan 11 at 7:48 # Perl 5 (-p), 102 bytes s/_+/__&/g,s/^|/ /gm,s/^ *\S /& /gm,s-( +)\\ -&/ 1 \\ \\ 1 / - for(\=' __ / \ \__/')x--_}{  Try it online! -p and }{ at the end is a trick to only print the output record separator \ at the end. It only works for one input record; the header is used to print all in one tio link. \=' __ / \ \__/' # output record separator initialized with hexagon (size 1) s/_+/__&/g,s/^|/ /gm,s/^ *\S /& /gm,s-( +)\\ -&/ 1 \\ \\ 1 / - # regexes to increase the hexagon by 1 for .. --_ # to repeat n-1 times where n is the input  • How does this work? Does _ effectively become a reference to \ inside the loop so that modifications to _ inside the loop propagate to \ outside the loop? Jan 8 at 5:59 • really i didn't know i've just tried and it worked. I think the x operator may copy the references Jan 8 at 8:33 # Haskell, 150 bytes r=reverse m(o:c:k)=o:c:c:c:k++" " f 1=[["\\ /","__ "],["/__\\"]] f n|[w:i,j]<-map m<>f(n-1),_:_:k<-rm w=[r k:w:i,k:j] h[i,j]=unlinesr<>r i++j h.f  Try it online! A more recursive version of this answer. The arbitrariness of this challenge makes this pretty frustrating. ## Explanation This answer is a bit hard to explain. The challenge is, as I already said, arbitrary in a few ways, so the code is sort of just a nest of symbols. ### Idea The idea of the program here is to build up the two halves. That is when calculating the nth hexagon we get the two halves for the n-1th hexagon and use that to make the next biggest one. There are some caveats though. We build the top half up-side-down and we build both halves mirrored left to right. We do this because it is convenient to do it this way. No deep reason it just makes things shorter even if it does make things a little incomprehensible. ### Details The first line is pretty straight forward r is an alias for reverse. The second line is not so straight forward. m is a nonsense function, it exists because it or a similar operation needs to be done in a few places. It doesn't really have a semantic meaning. The best explanation of what it does here is the code. m(o:c:k)=o:c:c:c:k++" "  From here we start getting to f which handles basically all of the logic. The first case for f is the base case, it is pretty standard f 1=[["\\ /","__ "],["/__\\"]]  Note that we return a list of two items instead of a tuple. In any sane program we would be using a tuple since it is fixed at 2 elements. However later we will map over both arguments of this with the same function. It is hard to do that with a tuple but easy with a list, and the list doesn't pose any drawbacks so we use it. Then we have the inductive case. First we fetch the previous case, and double map our m over it. This makes the hexagon 1 unit wider (2 characters) and moves it half a unit (1 character) to the right (although since this whole thing is backwards the space characters are added on the right). We pattern match this to [w:i,j] because we want to use w to make new rows later. Speaking of which next we make the rows. We do this with a pattern match: _:_:k<-rm w  This is sort of nonsense code. It just slaps together things we already had to produce the correct output. k and its reverse form the new rows so we add them in. and return that. After f we have h which turns the output of f into a string. It undoes all the wacky transforms we used during the construction and packages it up to be used. With all that we just compose f and h for the final function. # Retina 0.8.2, 94 bytes .+ * ¶&* \G ¶%'/%_%_\ r \G %\'%_%_%'/¶ ^¶( *) 1 .&*_.&*_& T \_ +/  Try it online! Link includes test cases. Explanation: .+ * ¶&*  Insert two rows of n spaces. \G ¶%'/%_%_\  Convert the first row into the top sides of the hexagon. r \G %\'%_%_%'/¶  Convert the second row into the bottom sides of the hexagon. ^¶( *) 1 .&*_.&*_&  Insert the top line. T \_ +/  Replace the bottom line. # Python 2, 119 114 bytes i=n=input() d=0 exec"k=i/n|d;print' '*i+'\_/'[~k]+'_ '[i-d<n]*2*(2*n+~i)+'\_/'[k]\nif i==d:d=i=-1\ni-=d|1;"*(n-~n)  Try it online! # JavaScript (ES6), 109 107 bytes w=>(x=0,W=w*4,i=g=y=>~y? /\\_[x++-W?y*!i|w/x|x>w*3?(x+~y+w)%W?(x+y)%W-w?1:3:2:4:x=i=0&y--]+g(y):'')(w*2)  Try it online! ### Commented w => ( // w = input x = 0, // initialize x to 0 W = w * 4, // W = total width i = // initialize i to a non-zero value g = y => // g is a recursive function taking y ~y ? // if y is not equal to -1: \n /\\_[ // list of characters x++ - W ? // if this is not the end of the row: y * !i | // if this is neither the first nor the last row w / x | // or x is less than or equal to w x > w * 3 ? // or x is greater than w * 3: (x + ~y + w) % W ? // if (x - y - 1 + w) mod W is not equal to 0: (x + y) % W - w ? // if (x + y) mod W is not equal to w: 1 // draw a space : // else: 3 // draw a '\' : // else: 2 // draw a '/' : // else: 4 // draw a '_' : // else: x = i = 0 & y-- // decrement y, set x and i to 0 and draw a linefeed ] + g(y) // append the result of a recursive call : // else: '' // stop the recursion )(w * 2) // initial call to g with y = w * 2  # C (gcc), 194 $$\\cdots\$$ 149 144 bytes Saved 13 14 19 bytes thanks to ceilingcat!!! p(n,c){for(;n--;)printf(L"/\\ _\n"+c);}i;t;f(n){p(n,2);for(i=t=p(2*n,3);i>=p(1,4);t=i/n?--i,1:t)i+=!p(!p(n+i<<!p(!p(n+~i,2),t),t&!i|2),!t)-2*t;}  Try it online! ### Explanation (before some golfs) p(n,c){for(;n--;) // Helper function to print putchar("/\\ _\n"[c]);} // one of '/', '\', ' ', '_' , or // newline n times, this function // also returns 0 i;t;f(n){ // Main function prints an n hexagon p(n,2); // Print n leading spaces for the 1st // line for( // Main loop i=t=p(2*n,3); // Set i and t to 0, // and print 2*n '_'s for the 1st line i>=p(1,4); // Loop until i goes below 0, and // print a newline // At the end of each loop: i+=1-2*t, // increment i for the 1st half // and then decrement i in the 2nd t=i/n?--i,1:t) // keep t as t unless i equals n, // then make t 1 and decrement i // In the main loop: p(n+~i,2), // print n-i-1 leading spaces p(1,t), // print a '/' in the 1st half and a // '\' in the 2nd p(n+i<<1,t&!i|2), // print the 2*(n+i) middle spaces // unless at the bottom print '_'s p(1,!t); // print a '\' in the 1st half and a // '/' in the 2nd }  # 05AB1E, 3329 25 bytes -4 (7) bytes thanks to Kevin Cruijssen! L+<'/úíºI·'_×š»∊¶¡ðs‡).c  Try it online! 05AB1E has a canvas builtin which might be useful, but is quite tricky to get working, this is just the mirror builtins º and ∊ and the centralize builtin .c. • 26 bytes by not only using the .c builtin, but the º and ∊ mirror builtins as well. Too bad ∊ doesn't work on lists apparently, otherwise the »∊¶¡ could have been just ∊.. And you're indeed correct that the Canvas builtin is pretty useless for challenges like this because it prints with overlapping lines, and there are multiple characters involved here. Jan 7 at 16:36 • Apparently the ∊ is supposed to work on lists, but after any list manipulation is done on a list it doesn't work anymore. I've just reported this 05AB1E bug, but for now the work-around »∊¶¡ has to be used I guess. Jan 7 at 17:25 # J, 50 47 bytes -3 thanks to Jonah! ' \/_'{~]|."1((0,]+2*|.)@=@i.,.3,3,~0~<:,])@+:  Try it online! ((0,]+2*|.)@=@i. ,. 3,3,~0~<:,])@+: 0 0 0 0 3 3 3 3 1 0 0 2 0 0 0 0 0 1 2 0 0 0 0 0 0 2 1 0 0 0 0 0 2 0 0 1 3 3 3 3 ]|."1 0 0 3 3 3 3 0 0 0 2 0 0 0 0 1 0 2 0 0 0 0 0 0 1 1 0 0 0 0 0 0 2 0 1 3 3 3 3 2 0 ' \/_'{~ ____ / \ / \ \ / \____/  • 48 bytes -- ' \/_'{~]|."1(#&0 3,(+2*|.)@=@i.,.3:_1}0~,~)@+: Jan 9 at 16:56 • 47 -- ' \/_'{~]|."1((0,]+2*|.)@=@i.,.3,3,~0~<:,])@+:. Probably a couple more bytes to be had in there... Jan 9 at 18:45 • @Jonah thanks, that's way more elegant! – xash Jan 10 at 15:35 # Python 3.8 (pre-release), 174 bytes n=int(input()) b,a,s="\/ " z,f=range(n),lambda c,d,t:((n-1-i)*s+c+2*(n+i)*s+d for i in t) print(f"{'_'*2*n:^{4*n}}",*f(a,b,z),*f(b,a,z[:0:-1]),f"{b:>{n}}{'_'*2*n}/",sep="\n")  Try it online! -1 byte thanks to @Duncan -8 bytes thanks to @Danis • With n,(b,a,s)=int(input()),"\/ " you can get rid of the r, saving a character. Jan 7 at 14:25 • Well spotted! I thought Python would think that \/ is an escape sequence. Jan 7 at 14:34 • 174 bytes Jan 10 at 13:30 # Haskell, 129 120 bytes g=mod f n|a<-n*4=[c|y<-[-n..n],x<-[0..a],let c|x<1='\n'|g x(n*3+1)>n,abs y==n='_'|g(x+y)a==1='/'|g(x-y)a<1='\\'|1>0=' ']  Try it online! • saved 9 thanks to @Wheat Wizard and @xnor. • Check @xnor answer and its big improvement on the approach to the problem (avoiding modulo and parallel lines) ! • Equivalent of my C answer We make cartesian coordinates using list comprehension |y<-[0..n*2],x<-[0..a] [c| ... ,let c| ... | ... | ... ] and we yeld the character needed based on x-y or x+y to draw lines.. We use modulo to draw multiple lines(2) Special case is for _ which doesn't need a x/y ratio but a range, we used modulo to do just one comparison > instead of an a>x>b like • Your && can be a , since its in a pattern guard. Jan 10 at 12:10 • Also g(x+y-n-1)a<1 is the same as g(x+y-n)a==1. Jan 10 at 12:18 • Nice solution! You can save some bytes by centering y and changing the underscore condition: Try it online! – xnor Jan 10 at 12:21 • 110: Try it online! – xnor Jan 10 at 12:59 # SlimSharp, 150 bytes I n=RI(),m=n;S b=new S('-',n*2).Pad(n*-3),l="/",r="\\";Action<I> x=a=>P(l.Pad(-a).Pad(4*n-a)+r);P(b);for(;m>0;)x(m--);l=r;r="/";for(;m<n;)x(++m);P(b);  https://dotnetfiddle.net/iXLzcO The fiddle differs slightly from the post because .Net Fiddle can't use the RI() function to read from the console. This is still the naiive version, without any recursive or coordinate mapping tricks. I'm unlikely to get shorter, because SlimSharp hasn't defined shortcuts for some of the relevant array and string functions yet. # C#, 227 bytes The full C# looks like this, and that's still assuming all the necessary using directives and that we get to abstract to a method. void H(int n){int m=n;string b=new string('-',n*2).PadLeft(n*3),l="/",r="\\";Action<int> x=a=>Console.WriteLine(l.PadLeft(a).PadRight(4*n-a)+r);Console.WriteLine(b);for(;m>0;)x(m--);l=r;r="/";for(;m<n;)x(++m);Console.Write(b);}  # Ruby, 141 bytes ->(n,g=->c,d{(1..n).map{|i|" "*(n-i)+d+" "*2*(n+i-1)+c}},l=g[?/,e=?\$.reverse){[" "*n+?_*n*2,g[e,?/],l[0..-2],l[-1].sub(/ +(?=\/)/,?_*n*2)]}  Try it online! If an upper underscore is allowed, then it would take a bit lesser bytes, while the hexagon is as pretty as it was earlier ;-) # Ruby, 114 bytes ->n{[" "*n+?_*2*n,(g=->c,d{(1..n).map{|i|" "*(n-i)+c+" "*2*(n+i-1)+d}})[?/,e=?\$$,g[e,?/].reverse," "*n+?‾*n*2]}


Try it online!

• you need 2*n underscores for the top and bottom. Jan 6 at 9:45
• @Razetime - my eyes missed that details, thanks :) Jan 6 at 9:54

# 05AB1E, 70 bytes

ð×©'_¹·×«©¶«©¹'/1Λ¹·Ì'.2Λ¹'\3.Λ«©„./.;©¶¡Â‚€»s'.ð:,¹3*>(£„._:„/\Â‡,


Try it online!

# Perl 5, 143 bytes

sub f{$n=pop;@b=map{join'',$"x($n-$_),'/','  'x($n+$_-1),'\\',$/}1..$n;join('',$"x$n,$u=__ x$n,$/,@b,map y|/\\|\\/|r,reverse@b)=~s| +/$|$u/|sr}  Try it online! sub f{$n=pop;             #n = input
@b=map{             #set array @b to line 2 - n+1
join'',           #join parts into a line string
$" x ($n-$_), #space times n-1 '/', #char / ' ' x ($n+$_-1), #space times n+iterator minus 1 '\\', #char \$/                #char newline
} 1..$n; #n lines join('', #return string of these joined:$" x $n, #n spaces$u = __ x$n, #n*2 underscores$/,               #char newline
@b,               #lines 2 to n+1 constructed above
map y|/\\|\\/|r,  #and bottom part which is the same
reverse@b       #as top part reversed and /\ rotated
)=~s| +/$|$u/|sr    #and change last spaces of last line to _'s
}


-18 bytes with xnor's fixes and removing unneeded spaces on the last line

s=' '
(!)=replicate
e=reverse
h n=unlines$(\m->(n!s++(2*n)!'_'++n!s):e(e<$>m)++init m++[(n-1)!s++'\\':(2*n)!'_'++"/"])$(\i->i!s++'\\':(4*n-2*i-2)!s++'/':i!s)<$>[0..n-1]


Try it online!

Ungolfed:

hex :: Int -> String
hex n = unlines $first: middle ++ (init$ reverse (map reverse middle)) ++ [last]
where
first = replicate n ' ' ++ replicate (2*n) '_' ++ replicate n ' '
f i = replicate i ' ' ++ "/" ++ replicate (n-i + 2*n + n-i -2) ' ' ++ "\\" ++ replicate i ' '
middle = map f [n-1,n-2..0]
last = replicate (n-1) ' ' ++ "\\" ++ replicate (2*n) '_' ++ "/" ++ replicate (n-2) ' '


# Vyxal, 60 bytes

ð*\_?*d+,(n-‹ð*\/n?+ð*d++\\+,)(nð*\\?d‹n-n›?=[\_|ð]*d++\/+,)


Try it Online!

# JavaScript (Node.js), 177 bytes

n=>[...Array((N=2*n)+1)].map((_,i,a,g=i>n,s=g?i-n-1:n-i,j=i&&N-i,r='_'.repeat(N),S=Z=>' '.repeat(Z))=>i?S(s)+'/\\'[+g]+(j?'':r)+S(g?j&&6*n-2*i:N+2*--i)+'\\/'[+g]:S(n)+r).join



Try it online!

Not the shortest but uses a different approach. Second in my series of text-writing programs which aren't the shortest, but help assemble a repertoire of array solutions.