g | x | w | all
Bytes Lang Time Link
028Pip211207T214931ZDLosc
068Julia 1.0220217T212250ZMarcMush
nanPython 3.8 prerelease211105T131700ZSeb
084Python 3.8211102T141308Zovs
107C gcc211103T031237Ztsh
016Japt211103T022935ZAZTECCO
082R211103T191829ZGiuseppe
074Ruby211102T155113ZG B
01605AB1E211103T154740Zovs
148C gcc211102T205834ZNoodle9
015MATL211102T183102ZLuis Men
01905AB1E211103T083620ZKevin Cr
186Kotlin211103T044012ZJohnWell
015Vyxal C211103T030247Zemanresu
3731J211102T221701ZJonah
025Charcoal211102T171301ZNeil
076Ruby211102T205349ZLevel Ri
025Vyxal j211102T164314Zwasif
7974Python 3 with numpy211102T141356Zm90

Pip, 39 29 28 bytes

FiYPZ*\$+REYaFlyP(" *"l*_Mi)

Attempt This Online!

Explanation

We create a structure out of 0's and 1's and then use it for both the micro- and macro-structure of the desired output.

YPZ*\$+REYa
          a  First command-line argument
        EY   Identity matrix of that size
       R     Reverse
    \$+      Scan on addition, giving a reversed triangular matrix
 PZ*         Palindromize each row
Y            Yank the resulting nested list into the y variable

For example, with an input of 3, y will be [[0;0;1;0;0]; [0;1;1;1;0]; [1;1;1;1;1]].

Fi...FlyP(" *"l*_Mi)
Fi                    For each macro-scale row i in
  ...                 (the above definition of y):
     Fly                For each micro-scale row l in y:
                 Mi       Map to each macro-scale element in row i:
              l*_           Multiply each element of l by it
                            (1 -> unchanged, 0 -> 0)
         (" *"     )      Index into that string, mapping 0 to " " and 1 to "*"
P*                  Print, joining into a single string by default

Julia 1.0, 68 bytes

~n=2n-1
!n=[' '^(2n^2-j*~n-i)*rpad('*'^~i,~n)^~j for i=1:n,j=1:n][:]

Try it online!

I wish Julia had a center function

output is a list of lines

Python 3.8 (pre-release), 111 100 bytes

f=lambda n,b=['*'],p=1:p>2 and b or f(n,[f'{2*r*l+l:^{(2*n-1)**p}}'for r in range(n)for l in b],p+1)

Try it online!

Nowhere near the best Python 3 answers, but it's got recursion. See my answer on the source SO question for an ungolfed version with the same mechanisms.

-11 bytes thanks to @ovs

Python 3.8, 91 86 84 bytes

-2 bytes thanks to Lynn!

lambda n:[f"{(o%n*'**'+'*').center(w:=2*n-1)*(o//n*2+1):^{w*w}}"for o in range(n*n)]

Try it online!

C (gcc), 107 bytes

m,x,y;f(n){for(y=n*n;y--;)for(x*=x=m=2*n-1;x--;)putchar(abs(x%m-n+1)+y%n<n&abs(x/m-n+1)+y/n<n?42:x?32:10);}

Try it online!

-1 byte by ceilingcat

Japt, 18 17 16 bytes

ÇÑÄ
ïÈçYçÑ ûUÌÃû

Try it

o_ÑÄ         - range [0..input] *2+1
ï          - pair each with itself
 È         - then pass pairs by f(X,Y)
  ç        - repeat result X times
   YçÑ    - repeat '*' Y times
ûNÑÉ       - centre pad
Ãû         - centre pad all

R, 82 bytes

function(n)write(c(" ","*")[1+(z=outer(c(n:1,2:n),1:n,"<="))%x%z],1,(2*n-1)^2,,"")

Try it online!

Ruby, 82 74 bytes

->n{(r=1.step n+=n-1,2).map{|x|r.map{|y|((?**y).center(n)*x).center n*n}}}

Try it online!

Good golfers copy, great golfers steal.

05AB1E, 16 bytes

L'*×j.ºиøā·<ט.C

Try it online!

L                -- range from 1 to n
 '*×             -- repeat "*" that many times
    j            -- pad to length n with spaces to the left
     .º          -- self-intersected mirror
       и         -- for each string, make a list of n copies
       ​ ø        -- transpose to get the rows of the big triangle
​​         ā       -- get the range from 1 to the number of rows (n)
          ​·<     -- double and decrement to get a list of the first n odd numbers
            ​×    -- repeat each string in the i-th row 2*i-1 times
             ​˜   -- flatten into a list of lines
              ​.C -- center and join by newlines

Try it with step-by-step output!

C (gcc), 160 153 148 bytes

p(c,n){n&&p(putchar(c),n-1);}r;t;l;i;f(n){for(r=0;r<n*n;p(10,1))for(t=r/n,l=r++%n,p(32,(n+~t)*(n*2-1)),i=t-~t;i--;p(32,n+~l))p(32,n+~l),p(42,l-~l);}

Try it online!

Saved 7 bytes thanks to ceilingcat!!!

MATL, 29 16 15 bytes

ZvG:!<~PtX*42*c

Try it online!

How it works

Consider input 3 as an example. The stack is shown upside down, with the most recent element below.

Zv    % Implicit input. Symmetric range
      % STACK: [1 2 3 2 1]
G:    % Push input again. Range
      % STACK: [1 2 3 2 1],
               [1 2 3]
!     % Transpose
      % STACK: [1 2 3 2 1],
               [1
                2
                3]
<~    % Less than?, negate; element-wise with broadcast
      % STACK: [1 1 1 1 1
                0 1 1 1 0
                0 0 1 0 0]
P     % Flip vertically
      % STACK: [0 0 1 0 0
                0 1 1 1 0
                1 1 1 1 1]
tX*   % Duplicate. Kronecker product
      % STACK: [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 1 1 1 0 0 0 0 0 0 0 0 0 0 0
                0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
                0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0
                0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0
                0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
                0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
                0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0
                1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
42*   % Multiply by 42 (ASCII for '*'). Convert to char
      % Implicit display. Char 0 is displayed as space
      % STACK: ['            *            '
                '           ***           '
                '          *****          '
                '       *    *    *       '
                '      ***  ***  ***      '
                '     ***************     '
                '  *    *    *    *    *  '
                ' ***  ***  ***  ***  *** '
                '*************************']

05AB1E, 19 bytes

·ÅÉεIL'*×.Bí€û×}˜.c

Try it online or verify all test cases.

Explanation:

·                # Double the (implicit) input-integer
 ÅÉ              # Push a list of all odd numbers smaller than or equal to this 2*input
   ε             # Map over each odd integer:
    IL           #  Push a list in the range [1,input] again
      '*×       '#  Repeat "*" each integer amount of times as string
         .B      #  Box this list of strings, adding trailing spaces to make them all of
                 #  equal length
           í     #  Reverse each so the spaces are leading
            €û   #  Palindromize each string
              ×  #  Repeat each the current odd integer amount of times
   }˜            # After the map: flatten the list of lists
     .c          # Join this list of strings by newlines, and centralize it
                 # (after which it is output implicitly as result)

Kotlin, 186 bytes

val p={n:Int->for(p in n downTo 1)for(l in n downTo 1)for(g in n-1 downTo 1-n)for(c in n-1 downTo 1-n)print(when{p+Math.abs(g)<=n&&l+Math.abs(c)<=n->'*'
g!=1-n||c!=1-n->' '
else->'\n'})}

Try it online!

Vyxal C, 15 bytes

ƛd‹?ɾ×*vømøĊ*;f

Try it Online!

ƛ            ;  # Map 1...n to...
   ?ɾ           # 1...input...
     ×*         # Asterisks
       vøm      # Each palindromised
          øĊ    # Centered
            *   # Repeated...
 d‹             # (2 * value) - 1 times
              f # Flatten
                # (C flag) output centered

17 bytes without the flag by appending a øĊ.

J, 37 31 bytes

' *'{~[:,./^:2[:*/~i.>:/|@i:@<:

Try it online!

-6 after seeing the phrase "Kronecker product" in m90's python answer, realizing that's what I was doing, and finding a golfier implementation in this essay.

Charcoal, 25 bytes

NθFθF⊕⊗ι«J×⊖⊗θ⁻κι×θιG↗↘θ*

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

Nθ

Input n.

Fθ

Loop over each row.

F⊕⊗ι«

Loop over each of the 2i+1 triangles in each row.

J×⊖⊗θ⁻κι×θι

Jump to the (bottom left of the) triangle.

G↗↘θ*

Draw the triangle.

24 bytes if a leading blank line is allowed:

NθFθ«M×⊖⊗θ⊗ιθF⊕⊗ι«G↖↙θ*←

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

Nθ

Input n.

Fθ«

Loop over each row.

M×⊖⊗θ⊗ιθ

Jump to the end of the row.

F⊕⊗ι«

Loop over each of the 2i+1 triangles in each row.

G↖↙θ*

Draw the triangle.

Move to the next triangle.

Ruby, 76 bytes

->n{(0...n*n).map{|i|((?**(i%n*2+1)).center(j=n*2-1)*(i/n*2+1)).center j*j}}

Try it online!

Vyxal j, 25 bytes

d‹£²ʁƛ?%›‛***Ḣ¥⋏n?ḭd›*¥²⋏

Try it Online!

I think mirroring might help, but cannot think of how

Python 3 with numpy, 79 74 bytes

lambda n:where(kron(*[c_[:n]>=abs(r_[1-n:n])]*2),*'* ')
from numpy import*

Try it online!

-5 thanks to ovs, with the use of where.

Step-by-step example of how it works:

>>> from numpy import*
>>> (n:=2)
2
>>> (Y:=c_[:n])
array([[0],
       [1]])
>>> (X:=r_[1-n:n])
array([-1,  0,  1])
>>> (Z:=Y>=abs(X))    # Broadcasts.
array([[False,  True, False],
       [ True,  True,  True]])
>>> (A:=kron(*[Z]*2))    # Listify, double, and unpack to give the same argument twice.
array([[False, False, False, False,  True, False, False, False, False],
       [False, False, False,  True,  True,  True, False, False, False],
       [False,  True, False, False,  True, False, False,  True, False],
       [ True,  True,  True,  True,  True,  True,  True,  True,  True]])
>>> (B:=where(A,*"* "))    # Select asterisk for true and space for false.
array([[' ', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', '*', '*', '*', ' ', ' ', ' '],
       [' ', '*', ' ', ' ', '*', ' ', ' ', '*', ' '],
       ['*', '*', '*', '*', '*', '*', '*', '*', '*']], dtype='<U1')