100
\$\begingroup\$

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!

\$\endgroup\$
0

110 Answers 110

1
\$\begingroup\$

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

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
.)+  # duplicate, add one, add the two numbers together
'*'* # multiply the result by '*'
n    # put a newline here
\$\endgroup\$
1
  • \$\begingroup\$ nice, i did mine before seeing yours, was about to refactor it to look like this \$\endgroup\$ – Claudiu Jun 10 '10 at 6:29
1
\$\begingroup\$

Q, 54

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

example:

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

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);
}
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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')}


    *
   ***
  *****
 *******
    *
\$\endgroup\$
1
\$\begingroup\$

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

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

\$\endgroup\$
1
\$\begingroup\$

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

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
\$\endgroup\$
2
  • \$\begingroup\$ Wait, does that display the trunk? \$\endgroup\$ – Johannes Kuhn Dec 12 '13 at 19:56
  • \$\begingroup\$ yes, :+1 would do that \$\endgroup\$ – prashanth Dec 12 '13 at 20:05
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Japt, 11 bytes

õ_ç* êÃp* û

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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

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.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks! Good catch! \$\endgroup\$ – cyclaminist Dec 23 '18 at 11:49
1
\$\begingroup\$

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.

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

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

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 12 bytes

G<N*‖↑¶M⊖θ←*

Try it online

explanation

G<N*             #Draw a triangle size input N with character "*"
      ‖↑           #Mirror the triangle so it is the right way round
        ¶          #Newline
         M⊖θ←    #move left input-1 
               *   #"*" character
                   #the result is implicitly printed
\$\endgroup\$
2
  • \$\begingroup\$ 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//… \$\endgroup\$ – Malivil Dec 19 '19 at 18:25
  • \$\begingroup\$ my bad @Malivil! I meant to add one, but forgot, thank you :) \$\endgroup\$ – mabel Dec 19 '19 at 18:33
1
\$\begingroup\$

Keg, 42 38 32 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|    #Repeat variable l times
    ⑬©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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ The whitespace is there to make it easier to read. The 180 char count is for the necessary characters only. \$\endgroup\$ – Ethan Gallagher Apr 30 '20 at 2:37
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Wheat Wizard Apr 30 '20 at 3:39
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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)

\$\endgroup\$
2
  • \$\begingroup\$ A good idea would be to append the name of a related rock song to each of your rockstar programs. \$\endgroup\$ – Razetime Sep 23 '20 at 16:56
  • \$\begingroup\$ 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! \$\endgroup\$ – Shaggy Sep 23 '20 at 16:59
1
\$\begingroup\$

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!

With comments:

#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/
#Jump to unnamed label if there are any spaces left
//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/*/
\$\endgroup\$
1
\$\begingroup\$

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.

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

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

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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) \$\endgroup\$ – tzot Dec 25 '08 at 20:06
0
\$\begingroup\$

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) + "*")
\$\endgroup\$
0
\$\begingroup\$

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

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

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)+'*'
\$\endgroup\$
0
\$\begingroup\$

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