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

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

• edited accordingly, thanks :-) – Sickboy Oct 25 '16 at 11:42
• Possible duplicate of Draw an asterisk triangle – Oliver Ni Oct 25 '16 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. – Sherlock9 Oct 25 '16 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. – James Oct 25 '16 at 16:08
• @JDL: No, why would you? Ah, now I understand what you meant by square... :-D – Sickboy Oct 26 '16 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! – CT14.IT Oct 26 '16 at 20:33
• This language is very interesting! I'll be watching this very closely from now on :p. – Adnan Oct 26 '16 at 21:24
• Haven't seen this language before... Looks interesting! I wonder what you'd get if you combined it with Jelly somehow... – Esolanging Fruit Oct 31 '16 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 – njzk2 Oct 25 '16 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 '16 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... – Dennis Oct 27 '16 at 4:09
• +1 for teaching me about center. Never knew that existed till now. – DLosc Oct 31 '16 at 4:38

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

# 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++ – matsjoyce Oct 25 '16 at 20:02

## 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$_;""}
***
*
***

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

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


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


# 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! – Magic Octopus Urn Oct 25 '16 at 18:01
• I can actually help for once: ;ƒ'*¹N·-×Nð×ì})û» use the new palindromize command. -2 bytes. – Magic Octopus Urn Oct 25 '16 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 :) – Emigna Oct 25 '16 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. :) – Kevin Cruijssen Apr 12 '19 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 – James Oct 25 '16 at 21:24
• @DJMcMayhem Heh, I don't think I will be able to reduce the byte count on this one – Luis Mendo Oct 25 '16 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... – James Oct 25 '16 at 21:27

# PHP, 95 bytes

for($c=str_pad,$m=$n=$argv;$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 :) – Quentin Oct 26 '16 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 – Luis Mendo Oct 25 '16 at 19:01
• @LuisMendo That's cool! Since it's a completely different approach, I'll let you have it. – James Oct 25 '16 at 20:57
• Ok, I'll post it! – Luis Mendo Oct 25 '16 at 21:18

# 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. – Hypino Oct 25 '16 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) – Kevin Cruijssen Oct 26 '16 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. – Numberknot Oct 26 '16 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. ;) – Kevin Cruijssen Oct 26 '16 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) – Kevin Cruijssen Oct 28 '16 at 9:39

$c=2;for($i=$a=$argv;$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" # 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 – ASCII-only Apr 12 '19 at 23:15 • @ASCII-only rats! Looks like I've got some more work to do! lol – 640KB Apr 12 '19 at 23:16 • – ASCII-only Apr 12 '19 at 23:17 • – ASCII-only Apr 12 '19 at 23:20 • @ASCII-only yep, nicely done! That's for sure the right approach! – 640KB Apr 12 '19 at 23:24 # 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 # 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. # 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. – Value Ink Oct 25 '16 at 17:34 ## Java 7, 156 bytes Fairly simple. Keeps track of lines with n, stars with j, spaces with s, and direction with d. I really just wanted a non-recursive Java answer on the board, but it doesn't hurt that it's also a bit shorter :) String f(int n){String o="";int j=n,s=0,i,d=0;for(;n-->0;o+="\n"){for(i=0;i++<s;)o+=" ";for(i=0;i++<j;)o+="*";d+=j<2?1:0;j+=d<1?-2:2;s+=d<1?1:-1;}return o;}  With line breaks: String f(int n){ String o=""; int j=n,s=0,i,d=0; for(;n-->0;o+="\n"){ for(i=0;i++<s;) o+=" "; for(i=0;i++<j;) o+="*"; d+=j<2?1:0; j+=d<1?-2:2; s+=d<1?1:-1; } return o; }  # 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 '16 at 9:16 # Haskell, 84 bytes f n|l<-div n 2,k<-[-l..l]=putStr$unlines[[" *"!!(fromEnum$abs x<=abs y)|x<-k]|y<-k]  • Nice solution! But I'm pretty sure you don't need the putStr and you can get rid of the fromEnum like this. – ბიმო Dec 31 '17 at 17:27 # 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 # C (gcc), 80 74 bytes Thank ceilingcat for 6 bytes -Du(x,k)=for(x=~n;x+=2,x<n;putchar(k)) i;j;f(n){u(i,10)u(j,i*i<j*j?32:42);}  Try it online! # J, 30 28 bytes -2 bytes thanks to FrownyFrog! ' *'{~[:(>.|.)@(*|."1)]\@#&1  Try it online! • ]\@#&1 is 2 shorter – FrownyFrog Apr 13 '19 at 16:16 • @FrownyFrog Yes, of course! Thank you! – Galen Ivanov Apr 13 '19 at 18:13 # Groovy, 66 Bytes {n->((n..1)+(2..n)).each{if(it%2>0){println(("*"*it).center(n))}}}  ## Explained: ((n..1)+(2..n)) - Reverse palindromize to n [n,..,1,..,n] .each{if(it%2>0){...} - Iterate through odd elements. println(("*"*it).center(n)) - Center n stars and print each on newline. • .each's code block could be {it%2&&println(("*"*it).center(n))}. – manatwork Oct 26 '16 at 8:35 ### PHP, 191 bytes $b=[];for($i=$a=$argv+1;$i>0;$i--){$i--;if($i<=1){$c=str_pad("*",$a," ",2)."\n";break;}$b[]=str_pad(str_repeat("*",$i),$a," ",2)."\n";}echo implode("",$b).$c.implode("",array_reverse($b));  Run like php -f golf_hourglass.php 15 # php -f golf_hourglass.php 15 *************** ************* *********** ********* ******* ***** *** * *** ***** ******* ********* *********** ************* ***************  The idea behind it is to create the top half (the part before the single *), then just echo the top part twice, but the second time in reverse order. • I think this is a better start for this task for(;$i<$a=$argv;$i+=2){$t=str_pad(str_pad("",$i+1,"*"),$a," ",2)."\n";$i?$s.=$t:$r=$t;}echo strrev($s)."\n".$r.$s; – Jörg Hülsermann Oct 25 '16 at 17:09
• for(;$i<$a=$argv;$i++){$t=str_pad(str_pad("",$i+1+$i%2,"*"),$a," ",2)."\n";$i%2?$s.=$t:$s=$t.$s;}echo\$s; this is better – Jörg Hülsermann Oct 25 '16 at 17:18
• Replace implode() with join() to save 6 bytes. – Alex Howansky Oct 25 '16 at 17:38
• Replace \n with an actual new line to save a byte. – Alex Howansky Oct 25 '16 at 17:39