# Draw an hourglass

Again inspired by a task for Programming 101 here's another challenge.

Input:

• A positive integer n >= 3. (has to be odd)

Output:

• n lines of asterisks, where the first line has n asterisks and every new line has two asterisks less than the line before. Until hitting 1 asterisk. From there every new line has two asterisks more than the line before until getting back to n asterisks. Spaces or something like spaces have to used to align the asterisks so that it really will look like an hourglass.

General rules:

• Trailing newlines are allowed but do not have to be used.
• indentation is a must.
• This is code-golf, so shortest answer in bytes wins.
• Since the course is taught in C++, I'm eager to see solutions in C++.

Test case (n=5):

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

• I don't see how this is the duplicate of "Draw an asterisk triangle". This has indentation and a down-up sequence where the triangle is only upwards. Oct 25, 2016 at 11:51
• Possible duplicate of Draw an asterisk triangle Oct 25, 2016 at 14:59
• @Oliver Considering OP wrote "Draw an asterisk triangle", I'm not entirely sure that calling this challenge a duplicate is fair. It is definitely related, though. Oct 25, 2016 at 16:01
• Since not everyone here knows the full context, OP originally posted the "Draw an asterisk triangle" and edited this challenge in as an additional challenge. We told them to remove that part and make it a different challenge (which they did). This challenge is not a duplicate. OP is doing what many high rep users, and even a few mods have recommended. Oct 25, 2016 at 16:08
• @JDL: No, why would you? Ah, now I understand what you meant by square... :-D Oct 26, 2016 at 8:34

## Charcoal, 6 bytes

Ｇ↘←↗Ｎ*


Dead simple. Draw a polyGon of *, with side length taken from an input Number, where the sides go down-and-right, horizontally left, and up-and-right:

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


Then autocomplete the outline and fill it.

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


Try it online!

• Hah, that's pretty bonkers! Oct 26, 2016 at 20:33
• This language is very interesting! I'll be watching this very closely from now on :p. Oct 26, 2016 at 21:24
• Haven't seen this language before... Looks interesting! I wonder what you'd get if you combined it with Jelly somehow... Oct 31, 2016 at 4:19

## Python 2, 57 bytes

N=n=input()
exec"print('*'*max(n,2-n)).center(N);n-=2;"*n


A full program. Goes line by line, printing the right number of asterisks centered.

A recursive function was longer (67 bytes):

f=lambda n,p='':p+n*'*'+'\n'+(1%n*' 'and f(n-2,p+' ')+p+n*'*'+'\n')


or

f=lambda n,p='':1/n*(p+'*\n')or f(n-2,p+' ').join([p+n*'*'+'\n']*2)

• I wanted to suggest trying to replace the max with an abs, but all I got is abs(n-1)+1, which is worse because the addition requires parenthesis Oct 25, 2016 at 21:39
• @njzk2 You can cut the parens by doing '*'*-~abs(n-1), but then it's the same length as '*'*max(n,2-n).
– xnor
Oct 25, 2016 at 23:02
• There's def f(n,s=''):r=s+'*'*n+'\n';return 1/n*r or r+f(n-2,s+' ')+r for 61 bytes, but it's still longer. Even with a leading newline, def f(n,s='\n'):r=s+'*'*n;return 1/n*r or r+f(n-2,s+' ')+r is still 58 bytes... Oct 27, 2016 at 4:09
• +1 for teaching me about center. Never knew that existed till now. Oct 31, 2016 at 4:38

# C++ Metatemplates, 186 bytes

With the explicit formula from my C answer the Metatemplates are competing!

template<int N,int X=N*N+N-1>struct H{enum{I=X/(N+1)-N/2,J=X%(N+1)-N/2-1};S s{(J==-N/2-1?'\n':((I>=J&I>=-J)|(I<=J&I<=-J)?'*':' '))+H<N,X-1>().s};};template<int N>struct H<N,-1>{S s="";};


Ungolfed:

using S=std::string;

template <int N, int X=N*N+N-1>
struct H{
enum{I=X/(N+1)-N/2,J=X%(N+1)-N/2-1};
S s{(J==-N/2-1 ? '\n' : ( (I>=J&I>=-J)|(I<=J&I<=-J) ?'*':' '))+H<N,X-1>().s};
};

template <int N> struct H<N,-1> {S s="";};


usage:

std::cout << H<5>().s;


### non-competing

Just for the sake of fun:

//T: Tuple of chars
template <char C, char...Tail> struct T { S r=S(1,C)+T<Tail...>().r; };

//specialization for single char
template <char C> struct T<C> { S r=S(1,C); };

//M: Repeated char
template <int N, char C> struct M { S r=S(N,C); };

//U: concatenates T and M

//specialization for Tail=M
template <int N, char C> struct U<M<N,C>> { S r{M<N,C>().r}; };

//specialization for Tail=T
template <char...C> struct U<T<C...>> { S r=T<C...>().r; };

//finally the Hourglass
template <int N, int I=0> struct H {
S s=U<
M<I,' '>,
M<N,'*'>,
T<'\n'>
>().r;
S r{s + H<N-2,I+1>().r + s};
};

//specialization for recursion end
template <int I> struct H<1,I> {
S r=U<
M<I,' '>,
T<'*','\n'>
>().r;
};


Usage:

std::cout << H<5>().r;

• +1 for beating PHP with the most long-winded part of C++ Oct 25, 2016 at 20:02

# V, 12 bytes

Àé*hòl3Äjxx>


Try it online!

I like challenges like this because I get to show off the advantages of V's 2D nature. Explanation. First, we need to create a string of n asterisks. So, we do this:

À           " Arg1 times:
é          " Insert the following single character:
*         " '*'


As a side note, this is directly equivalent to @ai*<esc> in vim, and register @a is pre-initialized to "arg1". This makes numeric input much more convenient.

Then, we move on character to the right with h. Here is the fun part:

ò           " Until an error is thrown:
l          "   Move one character to the right. This will throw an error on anyline with only one asterisk in it
3Ä        "   Make 3 copies of this line
j       "   Move down one line
xx     "   Delete two characters
>    "   Indent this line once.


Now technically, this last part is

òl3Äjxx>>ò


Because the indent command is actually >>. V conveniently assumes incomplete commands apply to the current line, and also implicitly fills in the second ò character for looping.

# Python, 78 bytes

So only with indentation:

f=lambda n,i=0:n>1and' '*i+'*'*n+'\n'+f(n-2,i+1)+' '*i+'*'*n+'\n'or' '*i+'*\n'


Usage:

print f(5)


## PowerShell v2+, 54 bytes

param($n)$n..1+2..$n|?{$_%2}|%{" "*(($n-$_)/2)+"*"*$_}  Takes input $n (guaranteed to be an odd integer), constructs two ranges with $n..1 and 2..$n and concatenates them together, then uses Where-Object to select only the odd ones with |?{$_%2}. Those are fed into a loop. Each iteration, we construct the appropriate number of spaces, string-concatenated with the appropriate number of asterisks. Those strings are left on the pipeline, and output via implicit Write-Output inserts newlines between them at program completion. ### Examples PS C:\Tools\Scripts\golfing> 3,5,7|%{.\draw-an-hourglass.ps1$_;""}
***
*
***

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

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


# C, 114 109 bytes

i,j;k(n){for(i=-n/2;i<=n/2;++i)for(j=-n/2;j<=n/2+1;++j)putchar(j==n/2+1?10:(i>=j&i>=-j)|(i<=j&i<=-j)?42:32);}


ungolfed:

i,j;
k(n){
for(i=-n/2;i<=n/2;++i)
for(j=-n/2;j<=n/2+1;++j)
putchar(j==n/2+1?10:(i>=j&i>=-j)|(i<=j&i<=-j)?42:32);
}


Previous recursive solution:

p(a,c){while(a--)putchar(c);}
f(n,i){p(i,32);p(n,42);p(1,10);}
g(n,i){if(n>1)f(n,i),g(n-2,i+1);f(n,i);}
h(n){g(n,0);}


# JavaScript (ES6), 66 bytes

f=(n,s="*".repeat(n))=>n>1?s+
+f(n-2).replace(/^/gm," ")+
+s:s


The idea here is to generate each hourglass from the previous: add a space at the beginning of every line, and both prepend and append n asterisks.

# 05AB1E, 212019 17 bytes

Saved 2 bytes thanks to carusocomputing

;ƒ'*¹N·-×Nð×ì})û»


Try it online!

Explanation

;ƒ                   # for N in [0 ... floor(input/2)+1]
'*                 # push an asterisk
¹N·-×            # repeat the asterisk input-N*2 times
Nð×ì        # prepend N spaces
}       # end loop
)      # wrap stack in a list
û     # palendromize
»    # join with newlines

• Ir"*"×.pRû - Got this far, face palmed when I realized how far off I was, saw you had answered, going to go try to learn iteration in this language now using this example. Thanks! Oct 25, 2016 at 18:01
• I can actually help for once: ;ƒ'*¹N·-×Nð×ì})û» use the new palindromize command. -2 bytes. Oct 25, 2016 at 18:04
• @carusocomputing: Thanks! I didn't know about the palendromize command (I hadn't refreshed the docs). Very useful. Have needed it several times before :) Oct 25, 2016 at 18:09
• 9 bytes, even in the legacy. Although I'm pretty sure the builtins ÅÉ and .c probably weren't available yet at the time you posted this. :) Apr 12, 2019 at 6:45

# MATL, 12 bytes

Q2/Zv&<~42*c


Try it online!

### Explanation

This makes use of the recently added symmetric range function.

Q     % Input n implicitly. Add 1
% STACK: 6
2/    % Divide by 2
% STACK: 3
Zv    % Symmetric range
% STACK: [1 2 3 2 1]
&<~   % Matrix of all pairwise "greater than or or equal to" comparisons
% STACK: [1 1 1 1 1
0 1 1 1 0
0 0 1 0 0
0 1 1 1 0
1 1 1 1 1]
42*   % Multiply by 42 (ASCII code of '*')
% STACK: [42 42 42 42 42
0 42 42 42  0
0  0 42  0  0
0 42 42 42  0
42 42 42 42 42]
c     % Convert to char. Implicitly display, with char 0 shown as space
% STACK: ['*****'
' *** '
'  *  '
' *** '
'*****']

• Nice! That's a cool feature. This is the only answer that came close to my V answer, so now I'm going to obsess on taking off one or two bytes. :D Oct 25, 2016 at 21:24
• @DJMcMayhem Heh, I don't think I will be able to reduce the byte count on this one Oct 25, 2016 at 21:25
• Yeah, I don't think I can either. There'll probably be a 4-byte Jelly answer in a couple minutes anyway, hahaha... Oct 25, 2016 at 21:27

# PHP, 95 bytes

for($c=str_pad,$m=$n=$argv[1];$n<=$m;$n+=$d=$d>0||$n<2?2:-2)echo$c($c('',$n,'*'),$m,' ',2)."
";


Instead of storing the rows in an array and then outputting everything, the for loop goes down until 1, and then goes back up to the original number.

# C++11, 93 bytes

#include<string>
using S=std::string;S f(int n,int i=0){S s=S(i,32)+S(n,42)+'\n';return n>1?s+f(n-2,i+1)+s:s;}


Slightly ungolfed:

std::string f(int n,int i=0){
auto s=std::string(i,' ') + std::string(n,'*') + '\n';
return n>1 ? s+f(n-2,i+1)+s : s;
}


Usage:

std::cout << f(5);

• Nice! one byte can be saved by assuming ASCII and replacing '\n' with 10 :) Oct 26, 2016 at 14:30

# MATL, 20 bytes

XyY>t1X!*t2X!+ZS42*c


Try it online!

• You can save a few bytes with the recently introduced symmetric range function: Q2/Zv&<~42*c Oct 25, 2016 at 19:01
• @LuisMendo That's cool! Since it's a completely different approach, I'll let you have it. Oct 25, 2016 at 20:57
• Ok, I'll post it! Oct 25, 2016 at 21:18

# C, 79 bytes

h(m,n,k){for(n=m++,k=n*m;--k;putchar(k%m?abs(k%m-m/2)>abs(k/m-n/2)?32:42:10));}


It splits the countdown variable k into row and column indices. If the column index is 0 (last char in a row), it outputs a newline character (10). Then it adjusts the row and column indices to be around the center asterisk. Then, abs(x) < abs(y) is a short condition for outputting a space.

# R, 77 bytes

M=matrix(" ",n<-scan(),n);for(i in 1:n)M[i:(n-i+1),i]="*";cat(M,sep="",fill=n)


Creates a character matrix, which it then prints out via cat, with fill=n making sure the lines align properly. Note that elements are stored in a matrix column-first (i.e the first two elements are M[1,1] and M[2,1], not M[1,2].)

# Java 7, 170 165 164 bytes

Thanks to @Hypino for saving 5 bytes.
Thanks to Kevin for saving 1 byte.

String c(int n,int x){String s,c,t=c=s=" ";int i=0;for(;i++<n;s+="*");for(i=x;i-->=0;c+=" ");for(i=x;i-->0;t+=" ");return(n=n-2)>=0?s+"\n"+c+c(n,++x)+"\n"+t+s:"*";}

• You can save 2 bytes by removing s= from s=s+"\n"and 2 more bytes by changing return(n=--n-1) to return(n=n-2) for a total of 4 bytes. Oct 25, 2016 at 23:04
• Hi. You can golf two parts: String s="",c="",t=""; to String s,c,t=s=c=""; (-2 bytes), and return(n=n-2)>=0?s+"\n"+c+c(n,++x)+ to return n-1>0?s+"\n"+c+c(n-2,++x)+ (-2 bytes again) Oct 26, 2016 at 9:40
• But @KevinCruijssen pattern not as expected after changing n=n-2->n-1>0 because n should be used in other argument of a function. Oct 26, 2016 at 10:15
• @Numberknot I know, but I also changed n to n-2 at that part. return(n=n-2)>=0 ... n being changed to return n-1>0 ... n-2 is still shorter. PS: You've thanked me for saving bytes, but haven't changed your code in your edit. ;) Oct 26, 2016 at 11:31
• @Numberknot Umm.. you still forgot my second tip. Anyway, here is a shorter variant: String c(int n,int x){String s,c=s="";int i=0;for(;i++<n;s+="*");for(i=x;i-->0;c+=" ");return n>1?s+"\n "+c+c(n-2,x+1)+"\n"+c+s:"*";} without the t (ideone test - 133 bytes) Oct 28, 2016 at 9:39

$c=2;for($i=$a=$argv[1];$i<=$a;$i-=$c*=$i<2?-1:1)echo str_pad(str_repeat("*",$i),$a," ",2)." ";  Saved a byte by using an actual new line instead of an "\r" # APL, 19 bytes ' *'[1+∘.≤⍨(⊢⌊⌽)⍳⎕]  Test:  ' *'[1+∘.≤⍨(⊢⌊⌽)⍳⎕] ⎕: 5 ***** *** * *** *****  Explanation:  ⎕ ⍝ read number ⍳ ⍝ 1..N ( ⌊ ) ⍝ at each position, minimum of ⊢ ⍝ 1..N ⌽ ⍝ and N..1 (this gives 1..N/2..1) ∘.≤⍨ ⍝ outer product with ≤ 1+ ⍝ add 1 to each value ' *'[ ] ⍝ 1→space, 2→asterisk  • Just remove 1+ and use an APL that has ⎕IO←0. – Adám Oct 31, 2016 at 9:16 # Canvas, 7 bytes ⇵｛*×］⤢┼  Try it here! Explanation: ⇵｛*×］⤢┼ ⇵ ceiling divide by 2 ｛ ］ map over [1..pop] * push * × repeat by the counter ⤢ transpose ┼ quad-palindromize with 1 overlap  +1 byte with support for even numbers # PowerShell, 54 50 bytes filter f{if($_-1){'*'*$_;($_-2)|f|%{" $_"}}'*'*$_}


Try it online!

# PHP, 104 88 bytes

for(;$i++<$argn;$a.='**',$i++>1?$o=$s.$o:1)$o.=$s=str_pad("*$a",$argn,' ',2)." ";echo$o;


Try it online!

This doesn't beat the lowest scores for PHP on this challenge, but it's just too crazy for me to throw away.

Okay, so I've golfed now it to be the (not for long) lowest score for PHP on this challenge, but it doesn't change the fact that it's still crazy.

\$ echo 7|php -nF hour.php
*******
*****
***
*
***
*****
*******

• 83? also huh, php has barewords too, although it's not useful here Apr 12, 2019 at 23:15
• @ASCII-only rats! Looks like I've got some more work to do! lol Apr 12, 2019 at 23:16
• Apr 12, 2019 at 23:17
• Apr 12, 2019 at 23:20
• @ASCII-only yep, nicely done! That's for sure the right approach! Apr 12, 2019 at 23:24

+?
Fx,i,j:i,-1,*" ",o,j,x-,+1,+j,-1,*"a",O
x-1
Fx,i,+1,j:i,x-,+1,*" ",o,j,*2,-1,*"a",O


Try it online!

Just two for loops.

• Nice, congrats :-) Sep 28, 2020 at 8:16

# J, 302826 25 bytes

-2 bytes thanks to FrownyFrog!

-3 bytes thanks to Jonah!

' *'#~](],.(-+:))i.@-<.i.


Try it online!

## Previous version:

' *'{~[:(>.|.)@(*|."1)]\@#&1


Try it online!

• ]\@#&1 is 2 shorter Apr 13, 2019 at 16:16
• 26 bytes: Try it online! Sep 25, 2020 at 2:08
• @Jonah Thank you! I have almost forgotten I solved this one :) Sep 25, 2020 at 6:32
• Got one more byte off, 25: Try it online! Sep 25, 2020 at 16:37
• @Jonah Great! You don't give up :) Sep 25, 2020 at 19:35

# VyxalC, 1413 11 bytes

-2 thanks to @Lyxal

½ʀƛd⁰ε×*;øm


Port of Emigna's 05AB1E solution.

Try it Online!

½ʀƛd⁰ε×*;øm    # Full program
ƛ     ;      # Map each n
½ʀ             # in range(0, input / 2 + 1):
*        # Repeat...
×         # the character *...
d⁰ε          # abs(2 * n - input) times
øm   # Palindromize
# Implicit output ($$$$C' flag): join the array on newlines and center each line

• Try it Online! for 11 bytes May 16, 2021 at 4:14

# UiuaSBCS, 16 bytes

≡&p⊏:" *"⊞≤.↥⇌.⇡


Try it!

Assumes the output must be a string or printed. If a character matrix is acceptable, remove the ≡&p for -3 bytes.

• ↥⇌.⇡ Range, duplicate, reverse, max. If the input is 5, this would create [4 3 2 3 4] from it.
• ⊞≤. Table with itself by less than or equal to. This creates the binary hourglass matrix.
• The rest is just converting to characters and printing.

# Vyxal 3j, 11 bytes

zU•×ᵂ½ṚᶻḊVṅ


Try it Online!

# Pip-l, 16 bytes

QP("* "_>BMCHUa)


Try It Online!

### Explanation

QP("* "_>BMCHUa)
a  ; Command-line argument
HU   ; Halve and round up
MC     ; Map this function to a square coordinate grid of that size:
_>B       ;   1 if x coord is greater than y coord, 0 otherwise
; This results in a matrix which is 1 below the main diagonal and
; 0 on or above it
("* "        ) ; Use that as an index into this string: 0 -> "*", 1 -> " "
; Print each element of the top-level list on a separate line (-l flag)


### Alternate 16-byte solution

QP" *"@$|*EYHUa HUa ; Halve argument and round up EY ; Identity matrix of that size$        ; Scan
*      ; each row
|       ; on logical OR
; This results in a matrix which is 0 below the main diagonal and
; 1 on or above it
QP" *"@          ; Index into a string and quad-palindromize, as before


# Pyth, 22 bytes

j+J.e+*dk*b\*_:1hQ2_PJ


A program that takes input of an integer on STDIN and prints the result.

Try it online

How it works

j+J.e+*dk*b\*_:1hQ2_PJ  Program. Input: Q
:1hQ2     Range from 1 to Q+1 in steps of 2. Yields [1, 3, 5, ..., Q]
_          Reverse
.e                   Enumnerated map with b as elements and k as indices:
*dk                 k spaces
*b\*             b asterisks
+                    Concatenate the spaces and asterisks
J                     Store in J
PJ  All of J except the last element
_    Reverse
+                      Concatenate J and its modified reverse
j                       Join on newlines
Implicitly print


# C, 195 191 Bytes

Should golf down a bit smaller

x,y,i;f(n){for(i=0;i<n;i+=2,puts("")){for(y=n-i;y<n;y+=2,putchar(32));for(x=i;x++<n;putchar(42));}for(i=n-2;~i;i-=2,puts("")){for(y=n-i+2;y<n;y+=2,putchar(32));for(x=i-1;x++<n;putchar(42));}}


We can test it here on ideone

# Ruby, 55 54 bytes

f=->n,s=0{puts a=' '*s+?**n;(f[n-2,s+1];puts a)if n>1}

• ?**n` works; you don't need the space there. Oct 25, 2016 at 17:34