Draw Concentric ASCII Hexagons

Python - 251, 240, 239 228

l=input()+[0];m=max(l);A=abs;R=range
for j in R(2*m+1):print''.join([[' \\'[(A(j-i+m-1)/2.in l)*(2*m-i)/(j-m-.5)>1],'/'][(A(3*m-i-j)/2.in l)*(i-m-j+.5)/(j-.5-m)>0],'_'][(A(m-j)in l)*(A(2*m-i-.5)<A(m-j))]for i in R(4*m)).rstrip()


Alternative approach (251):

l=input()+[0]
l.sort()
m=max(l)
M=2*m
s=[[' ']*m*4for j in' '*(M+1)]
for i in l:
I=2*i;s[m-i][M-i:M+i]=s[m+i][M-i:M+i]='_'*I
for k in range(i):K=k+1;s[m-k][M-I+k]=s[m+K][M+I-K]='/';s[m-k][M+I-K]=s[m+K][M-I+k]='\\'
for t in s:print''.join(t).rstrip()


CJam, 148116 109 bytes

This took a lot longer than I expected. Originally, I just wanted to iteratively build the upper left quadrant, as in the diamond challenges, and then get the rest from mirroring. But I didn't notice that the underscores don't obey mirror symmetry between the upper and lower half. So I had to redo most of that, to generate the right half iteratively and then only mirror once (to the left).

S]2[l~]:(f#:+2bW%{_,2/~:T;{IT):T1<'\'/?S?S++}%__,2/=,2/I'_S?*_S+a@+\I'/S?S++a+}fI{)T)2*2$,-*1$W%"\/"_W%er@N}/


Test it here.

A Fibonacci-esque example:

8 3 1 5 2

        ________________
/                \
/                  \
/     __________     \
/     /          \     \
/     /   ______   \     \
/     /   / ____ \   \     \
/     /   / / __ \ \   \     \
/     /   / / /  \ \ \   \     \
\     \   \ \ \__/ / /   /     /
\     \   \ \____/ /   /     /
\     \   \______/   /     /
\     \            /     /
\     \__________/     /
\                    /
\                  /
\________________/


Explanation:

As stated at the top, I start by building the right half iteratively. That is, initially I've got only a single space in the grid, and then for each possible ring, I either surround the existing grid in spaces or a new semi-hexagon.

Once that's done, I mirror each line to the left and pad it with leading spaces for correct alignment. Here is a breakdown of the code:

"Prepare the input and the grid:";
S]2[l~]:(f#:+2bW%
S]                "Push string with a space and wrap it in an array. This is the grid.";
2               "Push a 2 for future use.";
[l~]           "Read and evaluate the input, wrap it in an array.";
:(         "Decrement each number by 1.";
f#       "Map each number i to 2^i.";
:+     "Sum them all up.";
2b   "Get the base two representation.";
W% "Reverse the array.":
"At this point, the stack has the proto-grid at the bottom, and an array of 1s and
0s on top, which indicates for each hexagon if it's present or not.";

"Next is a for loop, which runs the block for each of those 0s and 1s, storing the
actual value in I. This block adds the next semi-hexagon or spaces.";
{ ... }fI

"First, append two characters to all existing lines:";
_,2/~:T;{IT):T1<'\'/?S?S++}%
_                            "Duplicate the previous grid.";
,2/                         "Get its length, integer-divide by 2.";
~:T;                     "Get the bitwise complement and store it in T. Discard it.";
{                 }% "Map this block onto each line of the grid.";
I                   "Push the current hexagon flag for future use.";
T):T               "Push T, increment, store the new value.";
1<'\'/?        "If T is less than 1, push \, else push /.";
S?      "If the current flag is 0, replace by a space.";
S++   "Append a space and add it to the current line.";

"So for hexagons this appends '\ ' to the top half and '/ ' to the bottom half.
For empty rings, it appends '  ' to all lines.";

"Now add a new line to the top and the bottom:"
__,2/=,2/I'_S?*_S+a@+\I'/S?S++a+
__                               "Get two copies of the grid.";
,2/                            "Get its length, integer-divide by 2.";
=                           "Get that line - this is always the middle line.";
,2/                        "Get ITS length, integer'divide by 2.";
I'_S?*                  "Get a string of that many _ or spaces depending on the
current flag.";
_S+               "Duplicate and a space.";
a@+            "Wrap in an array, pull up the grid, and prepend the line.";
\           "Swap with the other copy.";
I'/S?      "Choose between / and a space depending on the flag.";
S++   "Append a space, and add both characters to the line.";
a+ "Wrap in an array, and append line to the grid.";

"This is all. Rinse and repeat for all rings. The result will look something like this:

_____
\
___   \
__ \   \
_ \ \   \
\ \ \   \
_/ / /   /
__/ /   /
___/   /
/
_____/

Note that there are still trailing spaces.";

"Finish up all lines. These will not be joined together any more, but simply left
on the stack in pieces to printed out back-to-back at the end of the program.
The following runs the given block for each line:";
{ ... } /

"This generates the necessary indentation, then mirrors the lines and puts them
in the right order:"
)T)2*2$,-*\_W%"\/"_W%er\N ) "Slice off that trailing space, but leave it on the stack."; T "Remember T? That still has something like the the size of the grid from the last iteration. In fact it's N-1, where N is the largest visible hexagon. We can use that to figure out how many spaces we need."; )2* "Increment and double."; 2$                   "Copy the current line.";
,-                 "Subtract its length from 2*N.";
*                "Repeat the space that often. This is our indentation.";
\_              "Swap with the line and duplicate.";
W%            "Reverse the line.";
"\/"_W%er   "Replace slashes with backslashes and vice versa.";
\  "Swap with the original line.";
N "Push a line break.";


APL (222 bytes in UTF-8)

(and 133 chars)

Since this question specifically asks for amount of bytes in UTF8 representation, I had to actually ungolf it a bit so that it is longer but its UTF8 representation is shorter. (In particular, the commute operator's character ⍨ is three bytes while () is only two, so that optimalisation doesn't work anymore, and it also makes assignment very expensive.)

{⎕←(~⌽∧\⌽⍵=' ')/⍵}¨↓⊃{⍵{⍺=' ':⍵⋄⍺}¨K↑(-.5×(K←⍴⍵)+⍴⍺)↑⍺}/{Z⍪⌽⊖Z←↑(⊂(⍵/' '),(2×⍵)/'-'),⍵{((-⍵)↑'/'),((2 4-.×⍵⍺)/' '),'\'}¨⌽⍳⍵}¨N[⍋N←,⎕]


Previous version, which is shorter in characters (124) but uses more bytes when represented in UTF-8 (230, which would put it in second place):

M←' '⋄{⎕←⍵/⍨~⌽∧\⌽⍵=M}¨↓⊃{⍵{⍺=M:⍵⋄⍺}¨K↑⍺↑⍨-.5×(K←⍴⍵)+⍴⍺}/{Z⍪⊖⌽Z←↑(⊂(⍵/M),'-'/⍨2×⍵),⍵{('/'↑⍨-⍵),'\',⍨M/⍨2 4-.×⍵⍺}¨⌽⍳⍵}¨N[⍋N←,⎕]


Test:

      {⎕←(~⌽∧\⌽⍵=' ')/⍵}¨↓⊃{⍵{⍺=' ':⍵⋄⍺}¨K↑(-.5×(K←⍴⍵)+⍴⍺)↑⍺}/{Z⍪⌽⊖Z←↑(⊂(⍵/' '),(2×⍵)/'-'),⍵{((-⍵)↑'/'),((2 4-.×⍵⍺)/' '),'\'}¨⌽⍳⍵}¨N[⍋N←,⎕]
⎕:
3 1 5 2
----------
/          \
/   ------   \
/   / ---- \   \
/   / / -- \ \   \
/   / / /  \ \ \   \
\   \ \ \  / / /   /
\   \ \ -- / /   /
\   \ ---- /   /
\   ------   /
\          /
----------