#C, 91 89 80 74 bytes
w,y;f(s){for(y=-s;++y<s;)for(w=printf("\n%*s",y,"");++w<s*printf(" *"););}
I pretty much tweaked around to get the correct formulas, then mashed it all together.
Call f
with the number n, and it will print the hexagon to stdout.
Ungolfed and explained (80-byte version):
w,y;
f(s) {
// y iterates over [-s + 1 ; s - 1] (the number of rows)
for(y = -s; ++y < s;)
// w iterates over [abs(y) + 2 ; s * 2]2 - 1] (the number of stars on the row)
for(
// This prints a backspace character (ASCII 8)
// padded with abs(y) + 2 spaces, effectively
// printing abs(y) spaces to offset the row.
// Also initializes w with abs(y) + 2.
printf("\n%*c", w = abs(y) + 2, 8);
// This is the for's condition. Makes use
// of the 2 returned by printf, since we coïncidentally
// need to double the upper bound for w.
w++ < s * printf("* ");
// Empty for increment
)
; // Empty for body
}
See it live on Coliru
Notes:
printf
can handle negative padding, which results in a left-aligned character with the padding on the right. Thus I tried something to the effect of w = printf("%*c*", y, ' ')
so it would take care of the absolute value, and I could retrieve it from its return value. Unfortunately, both zero and one padding widths print the character on its own, so the three center lines were identical.
Update: Jasen has found a way to do exactly this by printing an empty string instead of a character -- 6 bytes shaved off!
The backspace character is handled incorrectly by Coliru -- executing this code on a local terminal does remove the leading space on each line.