Code Golf Christmas Edition: How to print out a Christmas tree of height N

Given a number N, how can I print out a Christmas tree of height N using the least number of code characters? N is assumed constrained to a minimum value of 3, and a maximum value of 30 (bounds and error checking are not necessary). N is given as the one and only command line argument to your program or script.

All languages appreciated, if you see a language already implemented and you can make it shorter, edit if possible - comment otherwise and hope someone cleans up the mess. Include newlines and White Spaces for clarity, but don't include them in the character count.

A Christmas tree is generated as such, with its "trunk" consisting of only a centered "*"

N = 3:

   *
***
*****
*


N = 4:

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


N = 5:

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


N defines the height of the branches not including the one line trunk.

Merry Christmas PPCG!

VBScript, 106 characters

n = WScript.Arguments(0)
For i = 1 To n
WScript.Echo Space(n-i+1) & String(2*i-1, "*")
Next
WScript.Echo Space(n) & "*"


Usage and output example:

> cscript christmastree.vbs 7 //nologo
*
***
*****
*******
*********
***********
*************
*


Golfscript - 27 chars

~:i,0+{.i\-(' '*\.)+'*'*n}%

~:i  # eval the command line arg, store in i
,0+  # create a list [0..i-1] add 0 to the end
{}%  # map this block over the list
.    # make a copy of the list element
i\-  # subtract the list element from i
(    # decrease by one more
' '* # multiply the result by ' '
\    # swap, so the list element is back on top of stack
'*'* # multiply the result by '*'
n    # put a newline here

• nice, i did mine before seeing yours, was about to refactor it to look like this – Claudiu Jun 10 '10 at 6:29

Q, 54

{-1(-:)[((x+(!)x),x)]$(((&)((!)(2*x))mod 2),1)#\:"*";}  example: q){-1(-:)[((x+(!)x),x)]$(((&)((!)(2*x))mod 2),1)#\:"*";} 10
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*


This is my first experience with code golf. So advices are welcome :)

C: 170 chars:

int main(){
int n,m=1,x;
scanf("%d",&n);x=2*n-1;
for(;m<x*n+n+2;m++)
printf("%c",m==x*n|m==x*n+n+1?42:m==x*n+1?10:m>x*n?32:!(m%(2*n-1))?10:!(m%x<n-m/x)&m%x<m/x+n+1?42:32);
}


It's in PHP.

<center><?$t=$_GET[1]*2-$i=1;while($i<=$t){echo str_repeat('*',$i).'<br>';$i+=2;}echo'*'?><center>  Total characters(with spaces):98 Total characters(with no spaces):97 Bytes:98 I did not see a solution using R. The code below may not be efficient, but it seems to work (170 characters with spaces if all code placed on one line): for(i in 1:4){ cat( paste( paste(rep(' ', (3-(i-1))), collapse=''), paste(rep('*', (2*i-1)), collapse=''), collapse=''), sep='\n'); if(i==4) cat(' * ', sep='\n')} * *** ***** ******* *  Javascript, 89 i=4 c=t="" while(i){o=c,j=(i--+1)*2-3 while(j--)o+="*" t=o+"\n"+t c+=" "}console.log(t+o)  Javascript 81 o=s='' for(a=3;a--;){l=s+=' ' for(k=a*2+1;k--;)l+='*' o=l+'\n'+o}console.log(o+l)  ><>: 136 chars This one's not going to win, but because Christmas is coming again, I thought fish needed a Christmas tree too! (pun intended) 1-:&1$>:> :1(?!v~$:> :1(?!vv ^-1o" "< ^-1o"*"<>~2+$1-:0(?!v~~&ao>" "o1-v
^                              oa<;o"*"^!?(1: <


It can be run as follows with the standard interpreter:

./fish.py christmas.fish -v 5


... for N=5. (If the file is called christmas.fish :P) In this way, one prepopulates the stack with the value 5. This is the closest I could get to a command-line argument.

JavaScript, 110 characters (2 relevant spaces)

function p(l)
{
o=''
for(c=0; c<=n+l; c++)
o += c < n - l ? ' ' : '*'
print(o)
}

n = parseInt(arguments[0])

for(l = 0; l < n; l++)
p(l)
p(0)


Ran using spidermonkey. $smjs christmas_tree.js 4 For Javascript Console 105 function p(l){o='';for(c=0;c<=n+l;)o+=c++<n-l?' ':'*';console.log(o)}n=+prompt();for(l=0;l<n;)p(l++);p(0)  Scala, 73 chars val n=args(0).toInt (1 to n):+1 foreach(i=>println(" "*(n-i)+"*"*(2*i-1)))  run as golf.scala 10  • Wait, does that display the trunk? – Johannes Kuhn Dec 12 '13 at 19:56 • yes, :+1 would do that – prashanth Dec 12 '13 at 20:05 Python 2 - 62 Bytes: i,x=input()*2,1 exec"print('*'*(x%i)).center(i);x+=2;"*(i/2+1)  Multiplying the input by two saves a byte because of the need for extra brackets. There may be a way to further golf the operations. Japt, 11 bytes õ_ç* êÃp* û  Try it online! Japt -R, 11 bytes ÇÑÄ î*Ãp* û  Try it Ç :Map the range [0,input) Ñ : Multiply by 2 Ä : Add 1 î* : Repeat * that many times Ã :End map p* :Push a * û :Centre pad each element with spaces to the length of the longest :Implicitly join with newlines  Lua, 100 99 bytes p,r,n=io.write,('').rep,arg[1]for i=0,n do p(r(' ',n-i+1),r('*',i*2+1),'\n')end p(r(' ',n+1),'*\n')  Try it online! Another Lua version, a little shorter. • Thanks! Good catch! – cyclaminist Dec 23 '18 at 11:49 PHP, 79 bytes while($argn)echo$r[]=str_pad(" ",1+$argn--).str_pad("",++$n*2-1,"*");echo$r[0];


Run as pipe with -nR or try it online.

• Save 2 bytes using variable variables: Try it online! – Night2 Oct 13 '19 at 13:50

Zsh, 77 64 bytes

Since all these old questions are now open, I think the oldest q. on codegolf.se needs a zsh answer!
Try it Online!

s=*;for ((;i<$1;))printf %$[$1+i++]s\\n$s&&s+=**
printf %$1s \*  Hat-tip to Alastair from Boxing Day 2008 NB: Putting the printf stuff in a function is no advantage... NB2: original for 77 bytes.. saved 12 bytes by eliminating quotes, braces, trailing newline Charcoal, 12 bytes Ｇ<Ｎ*‖↑¶Ｍ⊖θ←*  Try it online explanation Ｇ<Ｎ* #Draw a triangle size input N with character "*" ‖↑ #Mirror the triangle so it is the right way round ¶ #Newline Ｍ⊖θ← #move left input-1 * #"*" character #the result is implicitly printed  • Nice answer! I took the liberty of creating a TIO link so others can see it in action, if you'd liked to edit it into your post: tio.run/##ASkA1v9jaGFyY29hbP//… – Malivil Dec 19 '19 at 18:25 • my bad @Malivil! I meant to add one, but forgot, thank you :) – mabel Dec 19 '19 at 18:33 Keg, 423832 23 bytes :&1ɧ1⑷:⑻$-⑬*$⑵;**⑸( '  Try it online! -9 bytes due to generating odd numbers inside of the map Answer History 32 Bytes ¿&1(⑻|:2+)1^⑷:;½ℤ⑻$-⑬*^**⑸(,
,


Try it online!

-6 bytes due to using a mapping approach

38 Bytes

:&®l1(©l|⑬©l*,:**,
,2+©l;®l)&⑬*,*,


-4 bytes due to ⑬ operator (space string)

Funny story: I almost said this was 40 bytes before I realised that I forgot how to count.

Try it online!

I might as well place up the Keg Christmas tree for the year seeing as how it's almost December!

Explained

:&®l    #Store the amount of lines in variable l and the register
1   #Push the number of stars per row
⑬©l*,   #Print that amount of spaces
:**,  #Print that amount of stars

,   #Print a literal newline
2+  #Increment the number of stars
©l;®l   #Update the amount of spaces to print
)
&⑬*,*,    #Print the bottom row


Java, 180 chars

interface a{static void main(String[]a){for(int N=new Byte(a[0]),i=-1;i++<N;p('*',i%N*2),p('\n',0))p(' ',N-i%N-1);}static<T>void p(T c,int i){System.out.print(c);if(i-->0)p(c,i);}}


I believe this is a new record for Java for this question!

interface a
{
static void main(String[]a){
for(int N=new Byte(a[0]),i=-1;i++<N;p('*',i%N*2),p('\n',0))p(' ',N-i%N-1);
}
static<T>void p(T c,int i){
System.out.print(c);
if(i-->0)p(c,i);
}
}


This program uses a recursive method to get rid of unnecessary for loops and print calls. Everything in main is run in one for loop.

• The whitespace is there to make it easier to read. The 180 char count is for the necessary characters only. – Ethan Gallagher Apr 30 '20 at 2:37
• Nice. I see that you have already included the reduced version as well. That would have been what I suggested, and it is generally best to include both versions. – Wheat Wizard Apr 30 '20 at 3:39

Batch, 132 129 bytes

@!! 2>nul||cmd/q/v/c%0 %1&&exit/b
for /l %%X in (1 1 %1)do set[= ![!
set]=![!*
:*
echo%]%
set]=%]:~1%**
2>x goto:*%]:~1%&echo%[%*


I shamelessly copied Golfing Delayed Expansion Variables in Batch to my batch script.
Uses the bizarre ability of GOTO :NUL to

allow execution of concatenated commands in the context of the caller

Edit 2020/5/1: Abused token delimiters to shorten variable names

MAWP, 45 bytes

=M@![![32;1-]M[42;1-]M2+=M10;1-][32;1-]42;


Try it!

Takes a while for N bigger than 10

Rockstar, 107 bytes

listen to N
X's0
while N-X
let X be+1
let Y be N-X
let Z be X*2-1
say " "*Y+"*"*Z

let N be-1
say " "*N+"*"


Try it here (Code will need to be pasted in)

• A good idea would be to append the name of a related rock song to each of your rockstar programs. – Razetime Sep 23 '20 at 16:56
• Not a bad idea, @Razetime, I might just do that - I already use song names for all my challenge titles. Of course, if I was anyway skilled at such things, I'd actually write a song in Rockstar related to the challenge! – Shaggy Sep 23 '20 at 16:59

sed 4.2.2, 62 bytes, -r flag

s/0\B/ /g
:
H
s/ (0+)/0\10/
//b
:a
s/0(0+)0/ \1/
ta
H
x
y/0/*/


Takes input in unary (e.g. 3 is 000), allowed as per meta consensus.

Try it online!

#Replace all zeroes except the last by a space
s/0\B/ /g
#Unnamed branch label
:
#Append to hold buffer
H
#Put zeroes around a stretch of zeroes
s/ (0+)/0\10/
//b
#Create a label a, and recursively remove initial/final zeroes
:a
s/0(0+)0/ \1/
ta
#Append to hold buffer
H
#Exchange hold/pattern buffers
x
#Replace 0s with asterisks
y/0/*/


Ruby 2.7, 50 bytes

->h{t=(0...h).map{" "*(h-_1)+?**(_1*2+1)};t<<t[0]}


Try it online!

TIO uses an older version of Ruby, whereas in Ruby 2.7, we've numbered parameters, which saves a byte.

First try in LUA

f=string.rep p=print function t(N) for i=0,N do s=f(" ",N-i) p(s..f("+",2*i-1)..s) end p(f(" ",N-1).."+"..f(" ",N-1)) end t(arg[1])


After selecting all of it scite tells me these are 131 chars

For clarities sake without optimizing away the \n etc:

f=string.rep
p=print
function t(N)
for i=0,N do
s=f(" ",N-i)
p(s..f("+",2*i-1)..s)
end
p(f(" ",N-1).."+"..f(" ",N-1))
end
t(arg[1])


For the python version by ΤΖΩΤΖΙΟΥ I get shown 115 chars... Hrm, some more things to optimize

• Note: all insignificant/irrelevant whitespace should be ignored, as per the question specifications. So, any beautifying/syntax-needed whitespace doesn't count, but a " " literal does count. So your fully expanded version has 119 chars (3 significant spaces) – tzot Dec 25 '08 at 20:06

Scala, 97 chars

This one gets n from command line.

Thanks to ΤΖΩΤΖΙΟΥ for the * operator

val n=args(0).toInt*2
(1.until(n,2))foreach{i=>println(" "*(n-i)+"* "*i)}
println (" "*(n-1) + "*")


Language: Erlang, Char count: 151

A little bit shorter Erlang version:

-module(x).
-export([t/1]).
t(N)->[H|_]=T=t(N,1),io:format([T,H]).
t(0,_)->[];t(N,M)->[[d(N,32),d(M,42),10]|t(N-1,M+2)].
d(N,C)->lists:duplicate(N,C).


When should run with command line argument

-module(x).
-export([t/1]).
t([N])->[H|_]=T=t(list_to_integer(N),1),io:format([T,H]),init:stop().
t(0,_)->[];t(N,M)->[[d(N,32),d(M,42),10]|t(N-1,M+2)].
d(N,C)->lists:duplicate(N,C).


Invocation:

\$ erl -noshell -noinput -run x t 11
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
*


Rhino Javascript shell: 117 chars minified

t=['*'];
for(i=1;i<arguments[0];++i)
{
s='*'+t[i-1]+'*';
for(j in t)
t[j]=' '+t[j];
t[i]=s;
}
t[i]=t[0];print(t.join('\n'));


minified:

t=['*'];for(i=1;i<arguments[0];++i){s='*'+t[i-1]+'*';for(j in t) t[j]=' '+t[j];t[i]=s;}t[i]=t[0];print(t.join('\n'));


results:

c:\>java -jar C:\appl\Java\rhino1_7R1\js.jar c:/tmp/Xtree.js 10
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*


Language: FoxPro 2.x for DOS (should work with Clipper too), Char count: 62

para n
for h=1 to n
?spac(n-h)+repl('*',2*h-1)
endf
?spac(n-1)+'*'


Language: Euphoria 147 chars (9 relevant spaces):

include get.e
object
a = command_line(),
t = 42
a = value( a[3] )
a = a[2]
for i = 1 to a do
puts(1, repeat( 32, a - i ) & t & 10)
t &= "**"
end for
puts(1, repeat( 32, a - 1 ) & 42 & 10 )


With only relevant whitespace:

include get.e
object a=command_line(),t=42a=value(a[3])a=a[2]for i=1to a do puts(1,repeat(32,a-i)&t&10)t&="**"end for puts(1,repeat(32,a-1)&42&10)
`