56
\$\begingroup\$

Today, we're going to make an ASCII hexagon. You must write a program or function that takes a positive integer n, and outputs a hexagon grid of size n, made up of asterisks. For example, a hexagon of size 2 looks like this:

 * *
* * *
 * *

While a hexagon of size 3 looks like this:

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

You may use any of the default input and output methods, for example STDIO/STDOUT, function arguments and return values or reading/writing a file.

You may assume that input is always valid, so if it's not a positive integer, your program may do whatever you want. You do however have to handle the special case of a size 1 hexagon, which happens to be a single asterisk:

*

Leading and trailing whitespace is allowed as long as the output is visually the same.

Examples:

1:
*

2:
 * *
* * *
 * *

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

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

5:
    * * * * *
   * * * * * *
  * * * * * * *
 * * * * * * * *
* * * * * * * * *
 * * * * * * * *
  * * * * * * *
   * * * * * *
    * * * * *

6:
     * * * * * *
    * * * * * * *
   * * * * * * * *
  * * * * * * * * *
 * * * * * * * * * *
* * * * * * * * * * *
 * * * * * * * * * *
  * * * * * * * * *
   * * * * * * * *
    * * * * * * *
     * * * * * *

12:
           * * * * * * * * * * * *
          * * * * * * * * * * * * *
         * * * * * * * * * * * * * *
        * * * * * * * * * * * * * * *
       * * * * * * * * * * * * * * * *
      * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * *
    * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * *
  * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * *
  * * * * * * * * * * * * * * * * * * * * *
   * * * * * * * * * * * * * * * * * * * *
    * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * *
      * * * * * * * * * * * * * * * * *
       * * * * * * * * * * * * * * * *
        * * * * * * * * * * * * * * *
         * * * * * * * * * * * * * *
          * * * * * * * * * * * * *
           * * * * * * * * * * * *

As usual, this is , so standard loopholes apply, and you should try to write the shortest possible program measured in bytes. Of course, some languages are inherently shorter or longer than others, so remember that the goal is not necessarily to have the shortest overall byte count, but to beat submissions in the same or similar languages.

May the best golfer win!

\$\endgroup\$
5
  • 19
    \$\begingroup\$ Why do we even have a hexagonal-grid tag? \$\endgroup\$
    – Pavel
    Commented Dec 26, 2016 at 7:25
  • 16
    \$\begingroup\$ Also, someone needs to write a hexagony solution. \$\endgroup\$
    – Pavel
    Commented Dec 26, 2016 at 7:40
  • \$\begingroup\$ If anyone wants to go for the bounty, you can probably reuse the output loop of my Hexagony answer over here. \$\endgroup\$ Commented Jan 19, 2017 at 9:01
  • 7
    \$\begingroup\$ "Could you make me a hexagon please?" - sure, here you go: i.imgur.com/1emYIia.png \$\endgroup\$ Commented Jan 28, 2017 at 18:45
  • \$\begingroup\$ @Pavel because a lot of operations on a hexagonal grid are distinct from on the more standard square grid, and portable between solutions to different problems. Such operations as coordinate manipulation, rotation, output layout, etc. \$\endgroup\$
    – Sparr
    Commented Jun 28, 2018 at 5:25

63 Answers 63

41
\$\begingroup\$

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.

\$\endgroup\$
11
  • 2
    \$\begingroup\$ Wow, that's genius. And you're beating all the golfing languages! \$\endgroup\$
    – DJMcMayhem
    Commented Dec 26, 2016 at 19:28
  • 7
    \$\begingroup\$ I wouldn't really call this using the Hexagony language, more like using bash (or some other shell) with the Hexagony interpreter as one of the commands. That would be e.g. hexagony -g $1|tr . \*, assuming the hexagony interpreter is named this way. \$\endgroup\$ Commented Dec 27, 2016 at 11:32
  • 3
    \$\begingroup\$ This would benefit from an actual, runnable command... \$\endgroup\$
    – jpmc26
    Commented Dec 28, 2016 at 2:20
  • 1
    \$\begingroup\$ @jpmc26 For a length 5 hex you would run ruby ./interpreter.rb -g 5|tr . \* \$\endgroup\$
    – Riley
    Commented Dec 28, 2016 at 2:32
  • 3
    \$\begingroup\$ @OlivierDulac The "program" is zero bytes. All of the work is being done by the "flags". \$\endgroup\$
    – Riley
    Commented Dec 28, 2016 at 13:50
20
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ Starting from this, you derive a non PEP8 but valid Python 3 code with 69 bytes, by int(input()) instead of input() and the usual print(' '*j+'* '*(2*n+~j)) replacing print' '*j+'* '*(2*n+~j) - cool code b.t.w. ;-) \$\endgroup\$
    – Dilettant
    Commented Dec 27, 2016 at 9:15
  • \$\begingroup\$ That is some seriously cool code! \$\endgroup\$ Commented Feb 12, 2017 at 18:11
15
+100
\$\begingroup\$

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.

\$\endgroup\$
0
13
\$\begingroup\$

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>

\$\endgroup\$
12
\$\begingroup\$

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

\$\endgroup\$
11
\$\begingroup\$

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:

  • 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.

\$\endgroup\$
2
  • \$\begingroup\$ w=printf("\n%*s",abs(y),"");++w<s*printf(" *"); \$\endgroup\$
    – Jasen
    Commented Dec 27, 2016 at 0:23
  • \$\begingroup\$ @Jasen I can't believe I missed that... Thanks! \$\endgroup\$
    – Quentin
    Commented Dec 27, 2016 at 9:00
8
\$\begingroup\$

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!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I don't understand what the "centralize" part does. When I remove it, I get an array of strings without the appropriate number of leading spaces. \$\endgroup\$
    – DJMcMayhem
    Commented Dec 26, 2016 at 15:59
  • 1
    \$\begingroup\$ @DJMcMayhem On an array, you can see it as if it's a string joined by newlines with the text center-aligned. This is what it does on input. \$\endgroup\$
    – Adnan
    Commented Dec 26, 2016 at 17:26
  • 1
    \$\begingroup\$ 10 bytes by changing F¹N+...}) to L+<... \$\endgroup\$ Commented Aug 11, 2022 at 11:16
8
\$\begingroup\$

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‘
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Phew, the explanation was overwhelming. \$\endgroup\$ Commented Dec 26, 2016 at 15:43
  • \$\begingroup\$ What would a "centralization atom" do? \$\endgroup\$
    – DJMcMayhem
    Commented Dec 26, 2016 at 15:53
  • \$\begingroup\$ @DJMcMayhem See the 05AB1E answer for an example. \$\endgroup\$ Commented Dec 26, 2016 at 15:56
7
\$\begingroup\$

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

    * * * * *
   * * * * * *
  * * * * * * *
 * * * * * * * *
* * * * * * * * *
 * * * * * * * *
  * * * * * * *
   * * * * * *
    * * * * *
\$\endgroup\$
6
\$\begingroup\$

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
\$\endgroup\$
5
\$\begingroup\$

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:      * * * *
\$\endgroup\$
2
  • \$\begingroup\$ lpad may be able to save you a few bytes. I'd also call the language pl/pgsql, but that raises questions about whether you have to count the do language plpgsql $$ and the closing $$;. Those would be best addressed on meta, if they haven't come up before. \$\endgroup\$
    – jpmc26
    Commented Dec 28, 2016 at 2:27
  • \$\begingroup\$ Also, why do you need multiple DECLAREs? Wouldn't a single one work? \$\endgroup\$
    – jpmc26
    Commented Dec 28, 2016 at 2:40
5
\$\begingroup\$

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                                       .
\$\endgroup\$
5
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ Could you use alert if you specify browser js? \$\endgroup\$
    – FlipTack
    Commented Jan 20, 2017 at 17:48
  • \$\begingroup\$ @FlipTack, not really, since I gradually build up the string (line by line). If I alerted it, it'd alert line by line, and not the whole thing. \$\endgroup\$
    – Luke
    Commented Jan 20, 2017 at 18:16
5
\$\begingroup\$

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

\$\endgroup\$
5
\$\begingroup\$

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

\$\endgroup\$
5
\$\begingroup\$

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).

\$\endgroup\$
7
  • 1
    \$\begingroup\$ This gives wrong solution for 1 - " *". I think it should be asterisk without space in front? \$\endgroup\$ Commented Aug 1, 2018 at 15:12
  • \$\begingroup\$ @АндрейЛомакин - From OP: "Leading and trailing whitespace is allowed as long as the output is visually the same." A single star is visually the same as a single star with a space in front of it or at least that was my interpretation ;-) \$\endgroup\$
    – ElPedro
    Commented Aug 1, 2018 at 17:42
  • \$\begingroup\$ But you are actually correct in that I contradicted what I have just said in my answer. I have updated the answer to clarify. Better now? BTW, nice job on finding an old answer and spotting a potential error. Respect. \$\endgroup\$
    – ElPedro
    Commented Aug 1, 2018 at 18:27
  • 1
    \$\begingroup\$ I was attempting this challenge myself, and can't come up with anything better, was studing yours for inspiration. \$\endgroup\$ Commented Aug 1, 2018 at 18:57
  • \$\begingroup\$ I hope my humble effort has helped you. Sure we Wiĺl have some fun golfing together in the future. Enjoy PPCG. I sure do ☺ \$\endgroup\$
    – ElPedro
    Commented Aug 1, 2018 at 22:53
4
\$\begingroup\$

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>

\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
3
+25
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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)
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Nice use of gu. \$\endgroup\$ Commented Jul 6, 2018 at 12:47
3
\$\begingroup\$

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
@
\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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]
\$\endgroup\$
3
  • \$\begingroup\$ You can save 1 byte by using (1-n...n) with 3 dots \$\endgroup\$
    – G B
    Commented Dec 26, 2016 at 23:04
  • \$\begingroup\$ Seems consensus is to include the output code (i.e. puts) in the char count. But re-reading the definition it only says your function should "output" the result which could be read as "return" the result. Cool solution. \$\endgroup\$ Commented Feb 12, 2017 at 18:37
  • \$\begingroup\$ @MatiasBjarland meta.codegolf.stackexchange.com/a/2456/15599 \$\endgroup\$ Commented Feb 13, 2017 at 0:46
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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)
   * * * *
  * * * * *
 * * * * * *
* * * * * * *
 * * * * * *
  * * * * *
   * * * *
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Welcome to the site! This is a code-golf competition so you ought to include your byte count. Also you can remove a lot of the whitespace present in this answer to shorten it. \$\endgroup\$
    – Wheat Wizard
    Commented Jun 25, 2018 at 16:18
  • \$\begingroup\$ Thanks for your input, Cat Wizard. I'm new to code golfing, and I suppose scheme isn't the best language for it, but I'll try to shorten it up, eliminate whitespace, and add a byte count on my next entry. \$\endgroup\$
    – Kevin
    Commented Jun 27, 2018 at 0:38
2
\$\begingroup\$

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:
   * * * * 
  * * * * * 
 * * * * * * 
* * * * * * * 
 * * * * * * 
  * * * * * 
   * * * * 
\$\endgroup\$
2
\$\begingroup\$

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));

\$\endgroup\$
1
  • 2
    \$\begingroup\$ A few improvements: for(j=c.length-2;j>-1;j--)c.push(c[j]) can be written as for(j=a-1;j;c.push(c[--j])) and for(i=0;i<a;i++){c.push(" ".repeat(a-i-1)+"* ".repeat(i+a-1)+"*")} could be for(i=0;i<a;c.push(" ".repeat(a-i-1)+"* ".repeat(a-1+i++));. The return statement could be shortened to return a-1?c.join\n:"*" In total, these changes save 18B (11+7+1). \$\endgroup\$
    – Luke
    Commented Dec 30, 2016 at 9:05
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
1
  • \$\begingroup\$ Palindromise is now , so this is 7 bytes: Try it Online! \$\endgroup\$ Commented Jul 14, 2023 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.