53
\$\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\$
  • 15
    \$\begingroup\$ Why do we even have a hexagonal-grid tag? \$\endgroup\$ – Pavel Dec 26 '16 at 7:25
  • 13
    \$\begingroup\$ Also, someone needs to write a hexagony solution. \$\endgroup\$ – Pavel Dec 26 '16 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\$ – Martin Ender Jan 19 '17 at 9:01
  • 6
    \$\begingroup\$ "Could you make me a hexagon please?" - sure, here you go: i.imgur.com/1emYIia.png \$\endgroup\$ – aditsu Jan 28 '17 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 Jun 28 '18 at 5:25

58 Answers 58

37
\$\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\$
  • 2
    \$\begingroup\$ Wow, that's genius. And you're beating all the golfing languages! \$\endgroup\$ – DJMcMayhem Dec 26 '16 at 19:28
  • 6
    \$\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\$ – Paŭlo Ebermann Dec 27 '16 at 11:32
  • 3
    \$\begingroup\$ This would benefit from an actual, runnable command... \$\endgroup\$ – jpmc26 Dec 28 '16 at 2:20
  • 1
    \$\begingroup\$ @jpmc26 For a length 5 hex you would run ruby ./interpreter.rb -g 5|tr . \* \$\endgroup\$ – Riley Dec 28 '16 at 2:32
  • 3
    \$\begingroup\$ @OlivierDulac The "program" is zero bytes. All of the work is being done by the "flags". \$\endgroup\$ – Riley Dec 28 '16 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\$
  • \$\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 Dec 27 '16 at 9:15
  • \$\begingroup\$ That is some seriously cool code! \$\endgroup\$ – Matias Bjarland Feb 12 '17 at 18:11
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\$
11
+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\$
10
\$\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\$
10
\$\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\$
  • \$\begingroup\$ w=printf("\n%*s",abs(y),"");++w<s*printf(" *"); \$\endgroup\$ – Jasen Dec 27 '16 at 0:23
  • \$\begingroup\$ @Jasen I can't believe I missed that... Thanks! \$\endgroup\$ – Quentin Dec 27 '16 at 9:00
9
\$\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\$
  • 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 Dec 26 '16 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 Dec 26 '16 at 17:26
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\$
  • 2
    \$\begingroup\$ Phew, the explanation was overwhelming. \$\endgroup\$ – Erik the Outgolfer Dec 26 '16 at 15:43
  • \$\begingroup\$ What would a "centralization atom" do? \$\endgroup\$ – DJMcMayhem Dec 26 '16 at 15:53
  • \$\begingroup\$ @DJMcMayhem See the 05AB1E answer for an example. \$\endgroup\$ – Erik the Outgolfer Dec 26 '16 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\$

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\$
  • \$\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 Dec 28 '16 at 2:27
  • \$\begingroup\$ Also, why do you need multiple DECLAREs? Wouldn't a single one work? \$\endgroup\$ – jpmc26 Dec 28 '16 at 2:40
6
\$\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\$
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\$

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\$
  • \$\begingroup\$ Could you use alert if you specify browser js? \$\endgroup\$ – FlipTack Jan 20 '17 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 Jan 20 '17 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\$

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\$
  • 1
    \$\begingroup\$ This gives wrong solution for 1 - " *". I think it should be asterisk without space in front? \$\endgroup\$ – Андрей Ломакин Aug 1 '18 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 Aug 1 '18 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 Aug 1 '18 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\$ – Андрей Ломакин Aug 1 '18 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 Aug 1 '18 at 22:53
4
\$\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\$
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\$
4
\$\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\$
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
    \$\begingroup\$ Nice use of gu. \$\endgroup\$ – AdmBorkBork Jul 6 '18 at 12:47
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\$
  • \$\begingroup\$ You can save 1 byte by using (1-n...n) with 3 dots \$\endgroup\$ – G B Dec 26 '16 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\$ – Matias Bjarland Feb 12 '17 at 18:37
  • \$\begingroup\$ @MatiasBjarland meta.codegolf.stackexchange.com/a/2456/15599 \$\endgroup\$ – Level River St Feb 13 '17 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\$
  • 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\$ – Sriotchilism O'Zaic Jun 25 '18 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 Jun 27 '18 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\$
  • 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 Dec 30 '16 at 9:05
2
\$\begingroup\$

Java, 157 149 129 127 bytes

s->{for(int j=~--s,t;++j<=s;p(s-~s-t,"* "),p(1,"\n"))p(t=j<0?-j:j," ");};<T>void p(int j,T s){for(;j-->0;)System.out.print(s);}
  • 8 bytes removed by Jonathan Frech.
  • 20 bytes removed by Kevin Cruijssen.
  • 2 bytes removed by Kevin Cruijssen.

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 149 bytes. \$\endgroup\$ – Jonathan Frech Jun 24 '18 at 12:22
  • 1
    \$\begingroup\$ 94 bytes. NOTE: Java 11 has String#repeat(int), but TIO is still JDK 10, hence the emulated repeat(String,int) method (with the same byte-count). The actual code in Java 11 would be: s->{for(int j=~--s,t;++j<=s;System.out.println(" ".repeat(t)+"* ".repeat(s-~s-t)))t=j<0?-j:j;} \$\endgroup\$ – Kevin Cruijssen Jun 26 '18 at 8:24
  • 1
    \$\begingroup\$ @Eugene Sure. :) In that case some things to golf in the current Java version (8+) for now: 129 bytes. \$\endgroup\$ – Kevin Cruijssen Jun 26 '18 at 10:04
  • 1
    \$\begingroup\$ @KevinCruijssen That's quite a heavy golfing here, updated it, thanks. \$\endgroup\$ – Eugene Jun 26 '18 at 21:07
  • 1
    \$\begingroup\$ Me again. Found one more thing to golf for -2 bytes. 127 bytes This can also be used to golf 1 byte in the Java 11 solution above. \$\endgroup\$ – Kevin Cruijssen Jun 28 '18 at 8:36
2
\$\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\$
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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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