g | x | w | all
Bytes Lang Time Link
104AWK250915T163004Zxrs
092Java180624T112100ZYevgen
057Knight220812T235555ZAiden Ch
123C gcc210711T123924Zmekb
063Excel210711T172135ZAxuary
099JavaScript Node.js210707T123028Zmekb
008Vyxal C210705T091246Zemanresu
010Japt R180625T090726ZShaggy
120APLNARS 60 chars190129T203531Zuser5898
nanHexagony + Bash Coreutils161226T140948ZRiley
017Charcoal180626T132021ZKevin Cr
070JavaScript Node.js180918T062340ZShieru A
103JavaScript Node.js180918T054026Zuser5812
077VBA Excel180805T101518Zremoel
105C# .NET Core180802T133656ZMaz
172ABAP180802T143320ZMaz
079Python 2161226T095555ZElPedro
079PHP170215T081619ZTitus
034K oK180629T122641Zmkst
015Jelly180626T024356Zuser2027
126Hexagony linear180626T091635Zuser2027
233Sisi180628T190100ZDLosc
089Kotlin180628T162824ZJohnWell
086Hexagony180628T043032Zuser2027
076QBasic180628T205004ZDLosc
048Powershell180626T000004Zmazzy
113Python 3180627T001059ZSlayerGa
023Pyth180626T140936ZSok
025APL Dyalog Unicode180626T040802ZBubbler
143Javascript ES6161228T154125ZBald Ban
111Python 2170119T084605ZYytsi
nan180625T153237ZKevin
044Perl 5 with na M5.010180625T092908ZDom Hast
072R180622T184659ZdigEmAll
009Canvas180622T180237Zdzaima
096Common Lisp170215T140027Zuser6516
051k170222T234203Zzgrep
081Retina170215T205245ZBusiness
083C170215T093913ZAlbert R
079Haskell170212T165646ZMaki
056Groovy170212T180801ZMatias B
098F#170212T115638ZLukas Bo
050Pyth170129T060336ZNick the
086PostgreSQL170128T204410Zaditsu q
076QBIC170124T130207Zsteenber
074SmileBASIC170124T052754Z12Me21
091PHP170119T020128ZCave Joh
111Python 3170119T213216Zgeorge
049Perl 6170119T090249Zsmls
nan161226T194609Zrahnema1
125Charly170102T235303ZLeonard
061Python 2161226T110446Zxnor
123tcl161230T040417ZAlejandr
024Jelly161226T142501ZErik the
nan161226T110606ZQuentin
081JavaScript ES6161226T124341ZLuke
077JavaScript ES6161226T103309Zedc65
054Ruby161226T210005ZLevel Ri
076JavaScript ES6161226T132825ZETHprodu
017V161226T071213ZDJMcMayh
01305AB1E161226T100531ZAdnan
083JavaScript ES6161226T104743ZNeil
161Batch161226T110825ZNeil
290postgresql9.6161226T085139Zandryk

AWK, 104 bytes

{for(;i++<=2*$1;print i<=$1?s[i]:s[$1-++x]){s[i]=sprintf("%"$1-i"s",X);for(k=$1+i-1;k--;)s[i]=s[i]"* "}}

Attempt This Online!

Java, 157 149 129 127 93 92 bytes

s->{for(int j=~--s,t;j++<s;System.out.println(repeat(" ",t=j<0?-j:j)+repeat("* ",s-~s-t)));}

Try it online!

Knight, 58 57 bytes

;=n+~1P;=i~1W>+1*2n=i+1iO+*' '=xI>=x-n iFx~x*'* '+1-*2n x

Try It Online!

C (gcc), 164 125 124 123 bytes

i,h;main(z,b)int**b;{z=atoi(b[1]);for(i=z--+z;i--;puts(""))for(h=z<i?z-i+z:i,printf("%*s",z-h,""),h-=~z;h--;)printf("* ");}

Try it online!

Excel, 63 bytes

=LET(r,2*A1-1,x,ABS(A1-SEQUENCE(r)),REPT(" ",x)&REPT("* ",r-x))

Link to Spreadsheet

The above spills the results to multiple cells. The 75 byte formula for a single cells answer is below.

=LET(r,2*A1-1,x,ABS(A1-SEQUENCE(r)),CONCAT(REPT(" ",x)&REPT("* ",r-x)&"
"))

JavaScript (Node.js), 121 99 bytes

i=>[...t=[...Array(i)].map((_,z)=>''.padEnd(i-z)+'* '.repeat(z+i)),...t.reverse().slice(1)].join`
`

Try it online!

Vyxal C, 8 bytes

ʁ+×*vṄøm

Try it Online!

ʁ        # Range(n) (0...n-1)
 +       # Plus n (n...2n-1)
  ×*     # That many asterisks
    vṄ   # Join each by spaces
      øm # Palindromise
         # (C flag) Center and join by newlines

Japt -R, 11 10 bytes

ưçSi*Ãû ê

Try it (or use TIO to run multiple tests)


Explanation

               :Implicit input of integer U
Æ              :Map the range [0,U)
 °             :  Postfix increment U
  ç            :  Repeat
   S           :    Space
    i*         :    Prepend asterisk
      Ã        :End map
       û       :Centre pad each string with spaces to the length of the longest string
         ê     :Palindromise
               :Implicitly join with newlines and output

APL(NARS) 60 chars, 120 bytes

{1≥k←⍵:'*'⋄⊃{(' '⍴⍨k-⍵+1),((2×k+⍵)⍴'* ')}¨(0..⍵-1),(⍵-2)..0}

test

  f←{1≥k←⍵:'*'⋄⊃{(' '⍴⍨k-⍵+1),((2×k+⍵)⍴'* ')}¨(0..⍵-1),(⍵-2)..0}
  f 1
*
  f 2
 * *  
* * * 
 * *  
  f 3
  * * *   
 * * * *  
* * * * * 
 * * * *  
  * * *

the only difficult is that (2×7)⍴'* ' would mean "repeat '* ' until you write the 14th character" so that would repeat '* ' 7 times...

Hexagony + Bash Coreutils, 0+3+8 = 11 Bytes

Includes +3 for -g flag and +8 for |tr . \* non-standard invocation (see this meta post)


Input is given as an argument to Hexagony. When the Hexagony interpreter is called with the -g N option it prints a hexagon of .s. We then use tr to replace those with *s.

Charcoal, 33 31 17 bytes

≔×*NθFθ«P^θ→→»‖B↓

-14 bytes thanks to @Neil.

Try it online (verbose) or Try it online (pure).

Explanation:

Put a string in a variable consisting of the input amount of *:

Assign(Times("*", InputNumber()), q);
≔×*Nθ

Loop the input amount of times by doing a for-each over the characters of this string:

For(q){ ... }
Fθ« ... »

Print the string in both a down-left and down-right direction, without moving the cursor position:

Multiprint(:^, q);
P^θ

And move two positions to the right at the end of every iteration:

Move(:Right); Move(:Right);
→→

After the loop, reflect everything downwards with one line overlap:

ReflectButterfly(:Down);
‖B↓

JavaScript (Node.js), 70 bytes

f=(n,i=n,w=" ".repeat(--i)+"* ".repeat(n++))=>w+(i?`
${f(n,i)}
`+w:"")

Try it online!

With one trailing space at the end of each line.

JavaScript (Node.js), 103 bytes

f=(n,m=n+--n)=>[...Array(m)].map((_,i)=>m-Math.abs(i-n)).map(e=>' '.repeat(m-e)+'* '.repeat(e)).join`
`

Try it online!

VBA (Excel), 77 bytes

Using Immediate Window and A1 as input.

a=[a1]-1:for x=-a to a:y=Abs(x):?space(y)StrConv(String(1+a*2-y,"*"),64):next

And for fun.

    a=[A1
   ]-1:For
   x=-a To 
 a:y=Abs(x):
?Space(y)StrC
 onv(String(
  1+a*2-y,"
   *"),64)
    :Next

C# (.NET Core), 106 105 bytes

Private method, takes the size as input and returns a string containing the hexagon.

Edit: Holy cow. I stared at this single-for-loop version for so long, finally figured out how to make it one byte shorter than the double-for-loop version!

string h(int s){var o="";for(int q=2*s,y=q;q*q>++y;o+=y%q>y/q-s&y%q>s-y/q?"* ":y%q<1?"\n":" ");return o;}

Try it online!

s is the size, x and y represent "coordinates" in the output string (position on the line & current line). In an earlier version I wrote this nice little passage: h>e?x>h-e:x. I found it very fitting, but unfortunately had to scrap it when optimizing my code.

I was initially worried about handling size = 1, but it turns out my code worked just fine. Phew!

Suggestions are welcome! :)


Previous 106 byte version with two for-loops: Try it online!

ABAP, 172 bytes

FORM h USING s.DO s * 2 - 1 TIMES.WRITE /''.DATA(y) = sy-index.DO s * 2 - 1 TIMES.IF sy-index > s - y AND sy-index > y - s.WRITE'*'.ELSE.WRITE ``.ENDIF.ENDDO.ENDDO.ENDFORM.

For ABAP I am pretty impressed by how short it turned out to be. I suppose having written the C# answer beforehand was helpful, but merely from an "understanding what to do" perspective, since the languages are so vastly different. There might be potential to save some bytes by using a single do-loop instead, but that would require a few calculations which in turn would have so much whitespace in them that it's likely going to be worse.

Test Cases

Size = 1, 5, 13
Output for 1Output for 5Output for 13
Has some leading and trailing whitespace thanks to how WRITE works, but luckily it's not an issue. In fact this saves us a whole byte with WRITE'*' including an implicit trailing space. Wow!

Explanation (also on Pastebin with syntax highlighting)

FORM h USING s. "ABAP subroutine
  DO s * 2 - 1 TIMES. "basically a simple for loop; loop over each line top to bottom
    WRITE /''. "Newline. No effect on first line for some reason. *shrug*
    "Also, WRITE /. works, too, but outputs TWO line feeds here. Ugh.
    DATA(y) = sy-index. "Save current index in loop to Y
    DO s * 2 - 1 TIMES. "Loop for each character left to right
      IF sy-index > s - y      "Check if we need to write a '*'
         AND sy-index > y - s. "by subtracting size from current line and vice versa
        WRITE'*'. "Print the '*'. WRITE has an implicit space after the output! 
      ELSE.
        WRITE ``. "Empty literal. CANNOT be '' or ' ' because then we don't get any output.
      ENDIF.      "Yeah, WRITE is odd. Don't ask.
    ENDDO.        "End of inner loop 
  ENDDO.          "End of outer loop
ENDFORM.          "End of subroutine

Python 2, 100 97 89 88 87 81 79 bytes

-1 from @Flp.Tkc

-6 again from @Flp

-2 with thanks to @nedla2004. I was trying to find how to get rid of the second slice but didn't think of that one :)

i=input()
a=[" "*(i-x)+"* "*(i+x)for x in range(i)]
print'\n'.join(a+a[-2::-1])

Try it online!

Creates an array for the top half then adds the reversed array minus the middle line then prints. Prints exactly "as is" apart from 1 which prints with a leading space (I guess that is allowed as a * is visually the same as a * with or without a leading space).

PHP, 83 79 bytes

for($p=str_pad;++$y<2*$n=$argn;)echo$p($p("
",1+$k=abs($n-$y)),4*$n-$k-2,"* ");

Run as pipe with -nR or try it online.


This is close to Kodos´ answer; but str_pad is shorter than str_repeat even when golfed.
And the ++ in the loop head saves some more.

K (oK), 44 38 34 bytes

Solution:

{(-a+3*x)$(2*x+a,:1_|a:!x)#\:"* "}

Try it online!

Example:

{(-a+3*x)$(2*x+a,:1_|a:!x)#\:"* "}4
("    * * * * "
"   * * * * * "
"  * * * * * * "
" * * * * * * * "
"  * * * * * * "
"   * * * * * "
"    * * * * ")

Explanation:

Create lists of * of the desired length and then left-pads them the required amount.

{(-a+3*x)$(2*x+a,:1_|a:!x)#\:"* "} / the solution
{                                } / lambda taking implicit argument x, e.g. 4
                             "* "  / the string "* "
                          #\:      / take (#), each-left (\:)
          (              )         / do this together
                       !x          / til x, range 0..x, e.g. 0 1 2 3
                     a:            / assign to variable a
                    |              / reverse it, e.g. 3 2 1 0
                  1_               / drop the first, e.g. 2 1 0
               a,:                 / append that to a, e.g. 0 1 2 3 2 1 0
             x+                    / add x, e.g. 4 5 6 7 6 5 4
           2*                      / multiply by 2, e.g. 8 10 12 14 12 10 8
         $                         / pad (negative means left-pad)
 (      )                          / do this together
     3*x                           / x multiply by 3, e.g 12
   a+                              / add a, e.g. 12 13 14 15 14 13 12
  -                                / negate, e.g. -12 -13 -14 -15 -14 -13 -12

Extra:

There is a leading space, this can be removed at the cost of 1 extra byte:

{(1-a+3*x)$(2*x+a,:1_|a:!x)#\:"* "}

Edits:

Jelly, 16 15 bytes

ḶU⁶ẋż+Ḷ⁾ *ẋƲŒḄY

Try it online!


Now beats V!

Hexagony (linear), 128 127 126 bytes

Note that this is not Hexagony, just a (meta-)language Timwi supported in Esoteric IDE, so this is not eligible for the bounty.

However this can be converted to a Hexagony solution (and I think it will be smaller than this solution) I may do that later. It takes more effort I did it over here.

The initial takes 3 bytes (e2 9d a2). Each newline takes 1 byte (0a).

❢?{2'*=(
A
if > 0
 "-"&}=&~}=&}=?&
 B
 if > 0
  }P0;'(
  goto B
 &{&'-{=-(
 C
 if > 0
  'P0;Q0;}(
  goto C
 {M8;{(
 goto A
@

No Try it online!. This only works in Esoteric IDE.

Annotated code:

❢?        # read input n
[n]
{2'*=(     # x = 2n-1
[x]
A
if > 0    # loop (x) from 2n-1 to 1
 "-      # a = x - n
 [a]
 "&}=&~}=&    # a = abs(a). Let K be this amount
 }=?&
 B
 if > 0       # print ' ' (a) times
  }P0;'(
  goto B
 &        # current cell = a (= K)
 {&       # a = n if K>0 else x
          # Note that K=abs(x-n). So if K==0 then x==n.
          # Therefore after this step a is always equal to n.
 '-{=-    # compute n-(K-n) = 2n+K
 (        # decrement, get 2n+K-1
 C
 if > 0   # print ' *' this many times
  'P0;Q0;}(
  goto C
 {M8;{    # print a newline, goto x
 (        # x -= 1
 goto A
@

Sisi, 233 bytes

0set n3
1set i1
2set d1
3set o""
4set j n-i
5jumpif j7
6jump10
7set o o+" "
8set j j-1
9jump5
10jumpif o12
11set d0-1
12set j n+i
13set j j-1
14jumpif j16
15jump19
16set o o+"* "
17set j j-1
18jump14
19print o
20set i i+d
21jumpif i3

Try it online!

Note: because Sisi has no way of taking input, this meta consensus allows for input to be inserted into the source code. For this program, the value of n should be inserted directly after n on line 1. In the code above, the value n = 3 is used.

Pseudocode

Because of Sisi's limitations, we have to generate and print one line at a time in order. So we run a loop in which i will go from 1 up to n and back down to 1:

i = 1
d = 1
while i > 0
  construct string of (n-i) spaces
  append to that (n+i-1) copies of "* "
  print it
  if i = n
    d = -1
  end
  i = i + d
repeat

Ungolfed version

10 set n 3
20 set i 1
30 set d 1

100 set o ""
110 set j n-i
120 jumpif j 140
130 jump 200
140 set o o+" "
150 set j j-1
160 jump 120

200 jumpif o 300
210 set d 0-1

300 set j n+i
310 set j j-1
320 jumpif j 340
330 jump 400
340 set o o+"* "
350 set j j-1
360 jump 320

400 print o
410 set i i+d
420 jumpif i 100

Kotlin, 113 89 bytes

24 bytes saved thanks to mazzy

{n:Int->for(o in 1-n..n-1){val c=Math.abs(o)
println("".padEnd(c)+"* ".repeat(2*n-c-1))}}

Try it online!

Hexagony, 91 87 86 bytes

?{2'*=&~}=&}='P0</0P}|@..;>;'.\};0Q/..\&(<>"-_"&}=\?_&\/8.=-\<><;{M/.(.(/.-{><.{&'/_.\

Try it online!

Finally did it.

Initially (before realizing how expensive loops are) I expect this may be able to fit in side length 5, but now it's hard enough to fit it into side length 6.

To get this I actually have to modify the linear code a little. In fact, writing this makes me realize a way to golf the linear code down by 1 2 byte.

QBasic, 76 bytes

INPUT n
FOR i=-n+1TO n-1
s=ABS(i)
?SPC(s)
FOR j=2TO 2*n-s
?"* ";
NEXT
?
NEXT

(This requires real QBasic, in which ?SPC(s) is expanded to PRINT SPC(s);, unlike QB64, in which it becomes PRINT SPC(s).)

Similar approach to my Sisi answer, except QBasic has ABS and so it's more efficient to run a FOR loop from -n+1 to n-1.

Powershell, 91 89 78 68 63 52 48 bytes

param($n)$n..1+1..$n|gu|%{' '*$_+'* '*(2*$n-$_)}

Test script:

$script = {
param($n)$n..1+1..$n|gu|%{' '*$_+'* '*(2*$n-$_)}
}

12,6,5,4,3,2,1 |%{
    $_
    . $script $_
}

Output (extra leading space):

12
            * * * * * * * * * * * *
           * * * * * * * * * * * * *
          * * * * * * * * * * * * * *
         * * * * * * * * * * * * * * *
        * * * * * * * * * * * * * * * *
       * * * * * * * * * * * * * * * * *
      * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * *
    * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * * *
  * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * *
  * * * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * * *
    * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * *
      * * * * * * * * * * * * * * * * * *
       * * * * * * * * * * * * * * * * *
        * * * * * * * * * * * * * * * *
         * * * * * * * * * * * * * * *
          * * * * * * * * * * * * * *
           * * * * * * * * * * * * *
            * * * * * * * * * * * *
6
      * * * * * *
     * * * * * * *
    * * * * * * * *
   * * * * * * * * *
  * * * * * * * * * *
 * * * * * * * * * * *
  * * * * * * * * * *
   * * * * * * * * *
    * * * * * * * *
     * * * * * * *
      * * * * * *
5
     * * * * *
    * * * * * *
   * * * * * * *
  * * * * * * * *
 * * * * * * * * *
  * * * * * * * *
   * * * * * * *
    * * * * * *
     * * * * *
4
    * * * *
   * * * * *
  * * * * * *
 * * * * * * *
  * * * * * *
   * * * * *
    * * * *
3
   * * *
  * * * *
 * * * * *
  * * * *
   * * *
2
  * *
 * * *
  * *
1
 *

Explanation:

param($n)           # define script parameter
$n..1+              # int range from n to 1 step -1; append
1..$n|              # int range from 1 to n
gu|                 # alias for Get-unique eliminates equal neighbors - here is 1,1 -> 1
%{                  # for each int from [n, n-1, n-2, ... 2, 1, 2, ... n-2, n-1, n]
    ' '*$_+         # string (' ' have repeated $_ times) append
    '* '*(2*$n-$_)  # string ('* ' have repeated 2*n-$_ times)
}

Python 3, 117 113 bytes

def h(s):n="\n".join;t=[" "*(s-i-1)+"* "*(s+i)for i in range(s-1)];return"%s\n%s\n%s"%(n(t),"* "*(2*s-1),n(t[::-1])

Generates the top, then the middle, then reverses the top to generate the bottom half.

Pyth, 23 bytes

jm.[*4Q*"* "+Qd\ +PUQ_U

Try it online

Explanation:

jm.[*4Q*"* "+Qd\ +PUQ_UQ   Trailing Q inferred, Q=eval(input())
                     _UQ   Reversed 0-range, yields [Q-1, Q-2, ... , 1, 0]
                  PUQ      Tailless 0-range, yields [0, 1, ... , Q-3, Q-2]
                 +         Concatenate them, yields [0 ... Q-1 ... 0]
 m                         Map d in the above to:
            +Qd              Q+d
       *"* "                 Repeat *_ that many times
  .[*4Q        \             Centre pad the above to length 4*Q
j                          Join on newlines, implicit print

APL (Dyalog Unicode), 40 36 35 33 27 25 bytes

(⍉⊖⍪1↓⊢)⍣2∘↑⍳↓¨∘⊂'* '⍴⍨+⍨

Assumes ⎕IO←0, i.e. zero-based indexing. The output contains one leading and one trailing spaces on each line.

Many thanks to @FrownyFrog and @ngn for lots of golfing.

Try it online!

How it works

(⍉⊖⍪1↓⊢)⍣2∘↑⍳↓¨∘⊂'* '⍴⍨+⍨  ⍝ Main function train
                 '* '⍴⍨+⍨  ⍝   Repeat '* ' up to length 2×⍵
            ⍳↓¨∘⊂          ⍝   Generate lower-right corner of the hexagon
          ∘↑               ⍝   Convert to matrix
(⍉⊖⍪1↓⊢)                   ⍝   Palindromize vertically and transpose
        ⍣2                 ⍝   ... twice

Javascript (ES6), 143 bytes

It's finally Christmas break (merry Christmas!), so I have some time for golfing.
And boy has it been a while - hence the large byte count.
Here goes:

c=[];a=a=>{for(i=0;i<a;i++){c.push(" ".repeat(a-i-1)+"* ".repeat(i+a-1)+"*")}for(j=c.length-2;j>-1;j--)c.push(c[j]);return a==1?"*":c.join`\n`}
console.log(a(3));

Python 2, 111 bytes

n=input()
l=range(n,2*n-1)
S=l+[2*n-1]+l[::-1]
W=range(1,n)
for w in W[::-1]+[0]+W:print" "*w+"* "*S[0];S=S[1:]

A boring, straightforward implementation (and a full program). Outputs a trailing whitespace at each line.

Testcases:

1:
*

2:
 * * 
* * * 
 * * 

3:
  * * * 
 * * * * 
* * * * * 
 * * * * 
  * * * 

4:
   * * * * 
  * * * * * 
 * * * * * * 
* * * * * * * 
 * * * * * * 
  * * * * * 
   * * * * 

racket/scheme

(define (f n)
  (define (s t n)
    (if (= n 0) t (s (~a t "* ") (- n 1))))
  (define (h t p a i)
    (if (= i 0)
        (display t)
        (let ((x (~a t (make-string p #\space) (s "" a) "\n"))
              (q (if (> i n) (- p 1) (+ p 1)))
              (b (if (> i n) (+ a 1) (- a 1))))
          (h x q b (- i 1)))))
  (h "" (- n 1) n (- (* 2 n) 1)))

testing:

(f 1)
*

(f 4)
   * * * *
  * * * * *
 * * * * * *
* * * * * * *
 * * * * * *
  * * * * *
   * * * *

Perl 5 with -na -M5.010, 44 bytes

say$"x abs,"* "x(2*"@F"-1-abs)for 1-$_..$_-1

Try it online!

Uses the same range as a few of the other answers.

R, 72 bytes

function(n,a=n-1)for(i in abs(a:-a))cat(rep(c('','*'),c(i,2*n-1-i)),'
')

Try it online!

Canvas, 9 bytes

╷⁸+* ×]/─

Try it here!

Beating the built-in :D

Explanation:

{╷⁸+* ×]/─  implicit "{"
{      ]    map over 1..input
 ╷            decrement: 0..input-1
  ⁸+          add the input: input..(input*2-1)
    * ×       repeat "* " that many times
        /   diagonalify that - pad each line with 1 less space than the previous
         ─  palindromize vertically

No idea why there's the huge padding, but it's allowed & I'm fixing that soon™. fixed? Hope I didn't break stuff

Common Lisp, 97 96 bytes

(lambda(x)(dotimes(i(1-(* x 2)))(format t"~v@t~v{* ~}~%"(set'c(abs(1+(- i x))))(-(* x 2)1 c)1)))

needed to figure out formula for:

a) how many spaces before text: |1+x-i| ~~ (abs(1+(- i x)

b) how many characters: 2x-1-|1+x-i| ~~ (-(* x 2)1 c)

idea for using dotimes and abs for looping from Strigoides's answer here

Ideas for improvement are welcomed

k, 51 bytes

`0:{x,|-1_x}@|{m:-1+2*x;{(x#" "),(2*m-x)#"* "}'!x}@

Explanation:

              {                                  }@ / function(x)
               m:-1+2*x;                            / m = (2*x)-1
                        {                    }'!x   / for x in range(0, x):
                         (x#" "),                   /   x*" " +
                                 (2*m-x)#"* "       /           m-x*"* "
             |                                      / reversed()
   {       }@                                       / function(x)
    x,                                              / x +
      |-1_x                                         /     reversed(x[1:])
`0:                                                 / print array line by line

Retina, 81 bytes

Assumes ISO 8859-1 encoding. All whitespace is significant.

\d+
$* $&$*a
^ 

.*
$0¶$0
m+`^(( *) (a+))¶\1
$1¶$2a$3¶$2a$3¶$1
m`^(a+)¶\1
$1
a
* 

Try it online!

Explanation

The code consists of 6 regex replacements on the input.

\d+
$* $&$*a

This replaces the input (we'll call it n) with n spaces and n as. I use a during most of program and replace it with * in the end because * is a reserved regex character and would need to be escaped if used directly.

^ 
​

(Note the space after ^) This removes the first space in the text. The result is a line consisting of n-1 spaces followed by n as.

.*
$0¶$0

The line is duplicated.

m+`^(( *) (a+))¶\1
$1¶$2a$3¶$2a$3¶$1

The most complicated stage in the program. It will replace any line that consists of a non-zero number of spaces followed by some number of as that also has an exact copy of itself following on the next line. It will be replaced with itself, a line consisting of 1 less space and 1 more a, that same line again, followed by the original line. More simply, it takes any two identical, directly adjacent lines and inserts two copies of a line with 1 less space and 1 more a in between them. This replacement will be made continually until the text stops changing, which happens when two lines consisting of only as have been inserted.

m`^(a+)¶\1
$1

This removes the duplicate of the line consisting of all as (since this line is the middle of the hexagon).

a
* 

Finally, replace all instances of a with * ​.

C, 88, 83

This solution uses just one for loop unlike the other C solution using 2 for loops because of this I suspect it can be golfed much further, but it's 4:30am so I'll attempt that tomorrow.

y,w;f(s){for(w=++s*2-1;y++<w*w-w*2;)printf(" %c",y%w?y%w-1<=abs(s-y/w-2)?0:42:13);}


Revision history:

2) y,w;f(s){for(w=++s*2-1;y++<w*w-w*2;)printf(" %c",y%w?y%w-1<=abs(s-y/w-2)?0:42:13);}

1) y,w;f(s){for(w=++s*2-1;y++<w*w-w*2;)printf("%s",y%w?y%w-1<=abs(s-y/w-2)?" ":"* ":"\n");}

Haskell, 99 97 79 bytes

h n=mapM_(putStrLn.(\k->([k..n]>>" ")++([2..n+k]>>"* ")))([1..n-1]++[n,n-1..1])

Explanation: This program is based on the observation that each line of a n-Hexagon contains (n-k) spaces followed by (n+k-1) asterisks, for some k dependent on the line number.

h n=                                             h is a function of type Int -> IO ()
  mapM_                                          mapM_ executes a function returning 
                                                 monadic actions on all objects 
                                                 in a list, in order. Then it executes 
                                                 these actions, in order. For this code, it 
                                                 transforms each value in the list into a 
                                                 monadic action that prints 
                                                 the corresponding line

      (                                          the function consists of two components
        putStrLn                                 the second part is printing the result of 
                                                 the first part to stdout 

        .                                        concatenating both components

        (\k->                                    the first parts first prints (n-k) spaces 
                                                 and then (n+k-1) asterisks

          ([k..n]>>" ")                          create the list of the integers from 
                                                 k to n (That is actually one more entry
                                                 than necessary, but just results in a
                                                 leading whitespace per line, while
                                                 saving 2 bytes compared to [1..n-k]).
                                                 Then create a new list where 
                                                 each element of that first list is 
                                                 replaced with the string " " and 
                                                 concatenate that result into one string

          ++                                     concatenate both lists

          ([2..n+k]>>"* ")                       create the list of the integers 
                                                 from 2 to n+k (of length n+k-1). 
                                                 Then create a new list where each 
                                                 element of that first list is replaced 
                                                 with the string "* " and concatenate 
                                                 that result into one big string
        ) 

      )         
      ([1..n-1]++[n,n-1..1])                     the list simply goes from 1 to n and 
                                                 back, supplying the k 

Edit: Switched to mapM_. I was not aware that was available without using import

Groovy, 64 63 62 58 56 bytes

{n->(1-n..n-1)*.abs().any{println' '*it+'* '*(2*n+~it)}}

Example call:

{n->(1-n..n-1)*.abs().any{println' '*it+'* '*(2*n+~it)}}(4)

produces:

   * * * *
  * * * * *
 * * * * * *
* * * * * * *
 * * * * * *
  * * * * *
   * * * *

F#, 101 98 Bytes

let r=String.replicate
let h n=for i in[0..n-1]@[n-2..-1..0]do(r(n-i)" ")+r(n+i)"* "|>printfn"%s"

Ungolfed:

let replicate = String.replicate
let ungolfed_hexagon n = 
  for i in [0..n-1]@[n-2..-1..0] do // For each hexagon line index [0 .. n-1 .. 0]
      (replicate (n-i) " ")  // Space padding
    + (replicate (n+i) "* ") // Hexagon stars
    |> printfn "%s"

Usage: Call h n, where n is the hexagon size, and it will print the hexagon.

Pyth - 60 57 50 bytes

p*tQd*Q"* "VtQp*-Q+2Nd*h+QN"* ";VtQp*hNd*-*tQ2N"* 

Try it online!

p                    print the next item (without trailing newline)
*tQd                multiply (input-1) by " "
*Q"*"                (implicit print) input times "* "
VtQ                 for all numbers 0 through (input-1) (as represented by N)
p                    print the next item (without trailing newline)
*-Q+2Nd              input-(N+2)  times " " (as represented by d)
*h+QN"*"            (implicit print) input+N+1  times "* "
;                    end for statement
V-Q1                 for all numbers 0 through input-1 (as represented by N)
p                    print the next item (without trailing newline)
*hNd                N+1 times " "
*-*tQ2N"*          (2*(input-1))-N   times "* " (implicit end string with EOF)
(implicit end of for loop with EOF)
(EOF == End of file)

PostgreSQL, 86

I was gonna write a CJam answer, but I saw somebody did Postgres and I had to compete :)

\prompt n
select lpad('',@i)||repeat('* ',2*:n-1- @i)from generate_series(1-:n,:n-1)i;

Run it like this: psql -Atf hex.sql dbname username and type in the number (or append e.g. <<<3 to the command).

QBIC, 82 76 bytes

Because you said please.

:~a=1|?A\[a-1|H=space$(a-b)┘G=A[a+b-2|G=G+@* `┘]Z=H+_tG|+H+@┘`+Z]?_fZ|+B+G+A

This can definitelyprobably be golfed further.

SmileBASIC, 74 bytes

FOR I=0TO N-1P
NEXT
FOR I=N-2TO.STEP-1P
NEXT
DEF P?" "*(N-I);"* "*(N+I)END

Adds a leading and trailing space.

These "hexagons" look horrible when the characters have the same width and height...

PHP, 91 bytes

for($r=str_repeat;$j<$h=($n=$argv[1])*2-1;)echo$r(' ',$a=abs(++$j-$n)).$r('* ',$h-$a)."\n";

Run it in the command line like this:

php -d error_reporting=0 -r "for($r=str_repeat;$j<$h=($n=$argv[1])*2-1;)echo$r(' ',$a=abs(++$j-$n)).$r('* ',$h-$a).\"\n\";" "5"

Ungolfed:

<?php
// Store reference to str_repeat function for repeated uses
$r = str_repeat;

// Loop through each line until n*2+1 (the height of the hexagon)
for(;$j < $h = ($n = $argv[1]) * 2 - 1;) {
    
    // Add spacing to the beginning of each line. 
    echo $r(' ', $a = abs(++$j - $n));
    
    // Add asterisks for each line 
    echo $r('* ', $h - $a);
    
    // Add newline to the end of the line
    echo "\n";
}

Python 3, 111 Bytes

d=int(input());i=' *';y=''
for x in range(d-1):y+=(' '*(d-x-1)+i*(d+x)+' '*(d-x)+'\n')
print(y+i*(2*d-1)+y[::-1])

Builds the top section, copies the reverse for the bottom and slots a line in the middle. Best approach I could think of.

Perl 6, 49 bytes

->\n{say " "x n*2-1-$_~"*"xx$_ for n...n*2-1...n}

Try it online!

How it works

->\n{                                           }  # Lambda accepting edge size (e.g. 3)
                               for n...n*2-1...n   # For each row-size (e.g. 3,4,5,4,3):
                       "*"xx$_                     # List of stars     (e.g. "*","*","*")
         " "x n*2-1-$_                             # Spaces to prepend (e.g. "  ")
                      ~                            # Concatenate.      (e.g. "  * * *")
     say                                           # Print

Octave , 62 58 bytes

@(n)' *'(dilate(impad(1,2*--n,n),[k='01010'-48;~k;k],n)+1)

Previous answer:

@(n)' *'(dilate(impad(1,2*(m=n-1),m),[k='01010'-48;~k;k],m)+1)

that can be called as

(@(n)' *'(dilate(impad(1,2*(m=n-1),m),[k='01010'-48;~k;k],m)+1))(5)

Try (paste) it on Octave Online

For example the base image for n=5 is

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

that can be created with

impad(1,2*(n-1),n-1)

The dilation morphological operator applied 4 times on the image using the following neighbor mask:

0 1 0 1 0
1 0 1 0 1
0 1 0 1 0

that can be created with [k='01010'-48;~k;k]

result of dilation:

0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0
0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0
0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0
0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0
0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0

then replace 0 and 1 with ' ' and '*' respectively

    * * * * *
   * * * * * *
  * * * * * * *
 * * * * * * * *
* * * * * * * * *
 * * * * * * * *
  * * * * * * *
   * * * * * *
    * * * * *

Charly, 125 bytes

let i="".promptn()let o=0let j=0let w=write loop{w(" "*(i-1-o),"* "*(i+o))w("
")if j<i-1{o+=1}else{o-=1}if o<0{break}j+=1}

Charly GitHub Page: https://github.com/KCreate/charly-lang

Python 2, 61 bytes

i=n=input()
while~-n+i:i-=1;j=abs(i);print' '*j+'* '*(2*n+~j)

Prints a trailing space at the end of each line.

Thanks to Erik the Outgolfer for saving a byte.

tcl, 123

Based in Python 2 ...

gets stdin i;set n $i;while {$n+[incr i -1]} {puts [string repe " " [expr abs($i)]][string repe "* " [expr 2*$n+~abs($i)]]}

Jelly, 24 bytes

R+’µạṀx@€⁶żx@K¥€”*$F€ŒḄY

Try it online!

Jelly is ashamed of the fact that it does not have a centralization atom, so it's beaten by 05AB1E and V. By 11 and 7 bytes respectively!

If you find any way to golf this, please comment. Any help is appreciated.

Explanation:

R+’µạṀx@€⁶żx@K¥€”*$F€ŒḄY Main link. Arguments: z.
R+’                      The sizes of the hexagon's rows. (implicit argument)
   µ                     Start a new monadic chain with the above argument.
    ȧṀx@€⁶               The spaces you must prepend to each row. (implicit argument)
           x@K¥€”*$      The stars (points) of each row, space-joined, as a single link. (implicit argument)
          ż        F€    Conjoin and merge the leading spaces with the stars appropriately.
                     ŒḄ  Create the second half of the hexagon without the middle row.
                       Y Join the rows with newlines. This makes the shape look like a hexagon.

Bonus: To find how many stars are there in a hexagon, use this:

Ḷ×6S‘

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 - 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:

JavaScript (ES6), 83 81 bytes

This is my first (code golf) answer. I hope I formatted everything correctly.

a=>{for(b=c=2*a-1;c;)console.log(" ".repeat(d=Math.abs(a-c--))+"* ".repeat(b-d))}

Unlike the 2 current ES6 answers, I'm not recursively calling a function and I am using the console for output.

JavaScript (ES6), 77 81 84

@Upvoters: don't miss the answer by @ETHproductions, that is 76 bytes

Edit Revised after change in spec, trailing space allowed

Just for the hat ... hey! No hat?

f=(n,b='* '.repeat(n+n-1),o=b)=>--n?f(n,b=` ${b}`.slice(0,-2),b+`
${o}
`+b):o

Test

f=(n,b='* '.repeat(n+n-1),o=b)=>--n?f(n,b=` ${b}`.slice(0,-2),b+`
${o}
`+b):o


function update()
{
  O.textContent=f(+I.value)
}

update()
<input id=I type=number min=1 value=3 oninput='update()'>
<pre id=O></pre>

Ruby, 54 bytes

->n{(1-n..n-1).map{|j|i=j.abs;' '*i+'* '*(n*2+~i)}*$/}

lambda function takes n as argument and returns a string separated by newlines. ($/ is a variable containing the default line separator.)

in test program

f=->n{(1-n..n-1).map{|j|i=j.abs;' '*i+'* '*(n*2+~i)}*$/}

puts f[gets.to_i]

JavaScript (ES6), 77 76 bytes

g=(n,s=`
*`+' *'.repeat(n*2-2),c=s,q=c.replace('*',''))=>--n?g(n,q+s+q,q):s

I told myself I wouldn't sleep until I had set a new ES6 record without looking at the other answers, so here it is...

Test snippet

g=(n,s=`
*`+' *'.repeat(n*2-2),c=s,q=c.replace('*',''))=>--n?g(n,q+s+q,q):s

for(var i = 1; i < 7; i++) console.log(g(i)) // joe

V, 17 bytes

é*À­ñ>{MÄpXA *Î.

Try it online!

As usual, here is a hexdump, since this contains unprintable characters:

00000000: e92a c0ad f13e 7b4d c470 5841 202a 1bce  .*...>{M.pXA *..
00000010: 2e                                       .

05AB1E, 14 13 bytes

Code:

F¹N+„ *×})û.c

Explanation:

F       }        # Input times do (N = iteration number)
 ¹N+             #   Calculate input + N
    „ *×         #   Multiply by the string " *"
         )       # Wrap everything into an array
          û      # Palindromize the array
           .c    # Centralize

Uses the CP-1252 encoding. Try it online!

JavaScript (ES6), 83 bytes

f=
n=>[...Array(n+--n)].map((_,i,a)=>a.map((_,j)=>j<n-i|j<i-n?``:`*`).join` `).join`
`
<input type=number min=1 oninput=o.textContent=f(+this.value)><pre id=o>

Batch, 161 bytes

@echo off
set s=*
set l=for /l %%i in (2,1,%1)do call 
%l%set s= %%s%% *
%l%echo %%s%%&call set s=%%s:~1%% *
echo %s%
%l%set s= %%s:~0,-2%%&call echo %%s%%

Note: Trailing space on line 2. Ungolfed:

@echo off
set s=*
rem build up the leading spaces and stars for the first row
for /l %%i in (2,1,%1) do call :s
rem output the top half of the hexagon
for /l %%i in (2,1,%1) do call :t
rem middle (or only) row
echo %s%
rem output the bottom half of the hexagon
for /l %%i in (2,1,%1) do call :b
exit/b
:s
set s= %s% *
exit/b
:t
echo %s%
rem for the top half remove a space and add a star to each row
set s=%s:~1% *
exit/b
:b
rem for the bottom half add a space and remove a star from each row
set s= %s:~0,-2%
echo %s%
exit/b

postgresql9.6, 290 bytes

do language plpgsql $$ declare s constant smallint:=4;declare n smallint;declare a constant int[]:=array(select generate_series(1,s));begin foreach n in array a||array(select unnest(a)t order by t desc offset 1)loop raise info'%',concat(repeat(' ',s-n),repeat(' *',s+(n-1)));end loop;end;$$

formatted sql is here:

do language plpgsql $$
declare s constant smallint := 4;
declare n smallint;
declare a constant int[] := array(select generate_series(1, s));
begin
foreach n in array a || array(select unnest(a)t order by t desc offset 1) loop
    raise info '%', concat(repeat(' ', s - n), repeat(' *', s + (n - 1)));
end loop;
end;
$$;

output:

INFO:      * * * *
INFO:     * * * * *
INFO:    * * * * * *
INFO:   * * * * * * *
INFO:    * * * * * *
INFO:     * * * * *
INFO:      * * * *