110
\$\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

116 Answers 116

1 2 3
4
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, 2008 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\$

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

Excessively long version in J (97 chars)

t=:3 :0
d=:0
k=:''
while.d<y
do.
k=:k,((d{((y-1)+>:i.y))$!.'*'((d{((|.i.y)))$,' ')),LF
d=:d+1
end.k,y$k
)

Run it this way:

t N

where N is tree height.

And Merry Xmas (a bit late).

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

Here's a Ruby Newbie (ha! It rhymes!) with his first working solution:

Ruby 164 characters (of readable code)

n=gets.to_i-1
(0..n).each do |j|  
    (n-j).times do 
        print " "
    end 
    (1+j*2).times do
        print "*" 
    end
    print "\n"
end
n.times do 
    print " "
end
print "*"
\$\endgroup\$
0
\$\begingroup\$

GolfScript, 34 characters

Another GolfScript entry:

~:x,-1%[x(]+{." "*x@- 2*("*"*n.},;

Explanation:

~:x                   #read input, store into x
,                     #create array [0,1,2,...,x-1]
-1%                   #reverse it
[x(]+                 #append x-1 to the array
{." "*x@- 2*("*"*n.}, #map each element in array to this block, outputs each line
;                     #remove results of map from stack

The block does:

{.                    #duplicate value given by map (stack is now: i i)
" "*                  #push " ", times it by i (stack now: i "   ") 
x                     #push x, stack is: (i "   " x), and bring i
@                     #bring i to the front (stack is: "   " x i)
- 2*(                 #pop x,i, push ((x-i)*2-1)
"*"*                  #print that many *'s
n.}                   #print newline, duplicate it so the map doesn't kill it
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 137 bytes

function k(a){var b="";for(i=0;i<a;i++){for(j=0;j<a*2;j++)b+=j>a-2-i
&&j<a+i?"*":" ";b+="\n"}for(i=0;i<a*2;i++)b+=i==a-1?"*":" ";return b}

Test case (formatting disorder is due to the first " marking a string):

k(3)

"  *   
 ***  
***** 
  *   "
\$\endgroup\$
0
\$\begingroup\$

R, 94 chars

Christmas is over, but anyway:

t=function(N){
  f=function(i)cat(rep(" ",N-i),rep("*",2*i-3),"\n",sep="")
  lapply(2:N,FUN=f);f(2)
}

For trees of height 2 or more:

> t(2)  > t(3)  > t(5)
*        *         *
*       ***       ***
         *       *****
                *******
                   *
\$\endgroup\$
7
  • \$\begingroup\$ We have posted similar R solutions in three minutes ;) \$\endgroup\$
    – djhurio
    Jan 8, 2014 at 14:37
  • \$\begingroup\$ becomes obsolete, see @djhurio solution \$\endgroup\$
    – popojan
    Jan 8, 2014 at 14:38
  • \$\begingroup\$ btw, I have got attracted to this site by the "2014" problem. I have got a 20 chars solution in R, but cannot post it as the question is protected from newbies ;) \$\endgroup\$
    – popojan
    Jan 8, 2014 at 14:51
  • \$\begingroup\$ Would be nice to see your 20 char solution for the "2014" ;) \$\endgroup\$
    – djhurio
    Jan 8, 2014 at 15:24
  • 1
    \$\begingroup\$ sum(T+T:exp(T+pi))-T \$\endgroup\$
    – popojan
    Jan 8, 2014 at 15:30
0
\$\begingroup\$

Python 2, 119 116

This one generates the tree on one line:

import sys
h=int(sys.argv[1])
print '\n'.join([" "*(h-i)+"*"*(i*2-1) for i in range(h,0,-1)][::-1]+[" "*(h-1)+"*"])

It's too bad you have to import the sys module in Python before being able to read argv.

Being used from Command Prompt:

C:\Users\User4\Desktop>treeprint.py 6
     *
    ***
   *****
  *******
 *********
***********
     *

I have a Linux box but it can't connect to the Internet and only has Python 2.4, in case you're wondering why I'm using Windows.

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

SOGL V0.12, 11 10 bytes

ƨ*αak} *¹╚

Try it Here!

Explanation:

     }      implicitly started loop, repeated input times
ƨ*          push "**"
  α         append that to the variable A, here defaulted to an empty string
   a        load the variable A
    k       remove the first characters
       *    push "*"
        ¹   wrap in an array
         ╚  center horizontally
\$\endgroup\$
0
\$\begingroup\$

Excel VBA, 72 Bytes

Anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window

For i=1To[A1]:[B1]=i:?Spc([A1]-i)[Rept("*",2*B1-1)]:Next:?Spc([A1-1])"*"
\$\endgroup\$
0
\$\begingroup\$

Python 3, 83 bytes

f=lambda n:'\n'.join([' '*(n-1-i)+'*'*(i*2+1)for i in range(n)])+'\n'+' '*(n-1)+'*'
\$\endgroup\$
0
\$\begingroup\$

Dart, 174 characters

main(p){var x=-1,r='',a=int.parse(p[0]),b=a,f=(x,y,[z='']){var s='';while(x-->0)s+=y;return s+z;};while(a-->0){x+=2;r+=f(a,' ')+f(x,'*','\n');}print('$r${f(b-1,' ','*')}');}
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 90 89 bytes

f=(l,n=1,s="")=>l+1?s+=f(l-1,n+2,l?`*`.repeat(n).padStart(l+n)+`
`:"*".padStart(n/2+1)):s

Try it online!


Alternative:

f=(l,n=1)=>l+1&&f(l-1,n+2,console.log(l?"*".repeat(n).padStart(l+n):"*".padStart(n/2+1)))

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ There's a padStart function in JavaScript?? And who says you never learn anything useful in CodeGolf... \$\endgroup\$ Apr 30, 2020 at 6:59
0
\$\begingroup\$

APL(NARS), 37 chars, 74 bytes

{⊃⍵{(' '⍴⍨⍺-⍵),'*'⍴⍨1+⍵×2}¨0,⍨0,⍳⍵-1}

test:

  h←{⊃⍵{(' '⍴⍨⍺-⍵),'*'⍴⍨1+⍵×2}¨0,⍨0,⍳⍵-1}
  h 5
     *    
    ***   
   *****  
  ******* 
 *********
     *    
  h 1
 *
 *
  h 2
  * 
 ***
  * 
  h 3
   *  
  *** 
 *****
   *  

Ot: It seems that your sys for know if i'am a human not work good in this chellphone (so I write this because possible this step is not taken)

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

Python3,81 bytes

n=int(input());
for j in range(n):
 print(' '*(n-j)+'*'*(2*j+1))
print(' '*n+'*')

try it online

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

Wren, 91 bytes

Fn.new{|n|
for(i in 0...n)System.print(" "*(n-i)+"*"*(2*i+1))
System.print(" "*n+"*")
}

Try it online!

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

x86 machine code, 42 40 bytes

Same limitation as in previous x86 answer (N < 10) applies. It may be lifted by replacing the first four lines with the following six (+6 bytes):

start:
    mov si, 82h
    lodsw
    xchg al, ah
    and ax, 0F0Fh
    aad

Assembly source code:

start:
    mov si, 82h
    lodsb
    aaa
    xchg ax, cx
    mov dx, 0A2Ah
    mov di, dx
    push cx
_loop:
    push cx
    rep stosb
    xchg ax, dx
    mov cx, bx
    rep stosb
    stosw
    inc bx
    inc bx
    pop cx
    xchg ax, dx
    loop _loop
    pop cx
    rep stosb
    xchg ax, dx
    stosw
    xchg ax, dx
    mov ax, 0924h
    stosb
    int 21h
    ret
\$\endgroup\$
0
\$\begingroup\$

SmileBASIC, 55 Bytes

Takes input from variable 'N'

FOR I=1TO N?" "*(N-I);"*"*(1+(I-1)*2)NEXT?" "*(N-1);"*"

I think it may be possible to shorten line 2 or 3 in the breakdown below

FOR I=1TO N                                                Iterate values of 'I' from 1 to N (One for each layer of branches)
           ?" "*(N-I)                                      Display spaces to offset asterisks, which begins at N-1 spaces long and end at 0 spaces long
                     ;"*"*(1+(I-1)*2)                      Display Asterisks
                                     NEXT                  End loop
                                         ?" "*(N-1);"*"    Display trunk
\$\endgroup\$
0
\$\begingroup\$

C++, 188 bytes

#include<iostream>    
using namespace std;
#define s string
int main(int a,char**c){int h=atoi(c[1]);for(int i=0;i<h;i++){cout<<s(h-i,' ')<<s(i*2+1,'*')<<endl;}cout<<s(h,' ')<<'*'<<endl;}

Ungolfed:

#include<iostream>

using namespace std;

int main(int a,char**c)
{
    int h = atoi(c[1]);
    for(int i=0; i<h; i++)
    {
        cout << string(h-i, ' ') << string(i*2+1, '*') << endl;
    }
    cout << string(h, ' ') << '*' << endl;
}
\$\endgroup\$
0
\$\begingroup\$

C# 3.0, 158 bytes

int n=int.Parse(a[0]);Console.WriteLine(Enumerable.Range(1,n).Concat(new int[]{1}).Select(x=>new string('*',x*2-1).PadLeft(x+n)).Aggregate((x,y)=>x+"\n"+y));

Ungolfed:

using System;
using System.Linq;
class Program
{
    static void Main(string[] a)
    {
        int n = int.Parse(a[0]);
        Console.WriteLine(Enumerable.Range(1, n).Concat(new int[] { 1 })
            .Select(x => new string('*', x * 2 - 1).PadLeft(x + n))
            .Aggregate((x, y) => x + "\n" + y));
    }
}
\$\endgroup\$
0
\$\begingroup\$

Lua, 113 significant chars

s=string.rep;n=tonumber(arg[1]);r=print;for i=0,n do l=s(" ", n-i)..s("*",(n-(n-i))*2+1);r(l)end r(s(" ",n).."*")
\$\endgroup\$
1
  • \$\begingroup\$ The two ns in s("*",(n-(n-i))*2+1) can be canceled out, yielding s("*",i*2+1). \$\endgroup\$ Dec 23, 2018 at 0:47
0
\$\begingroup\$

SAS, 70 87 bytes

87 bytes. With a pop window for N input.

data;
window _ n;
display _;
do i=1to n;
s=repeat('*',i*2-2);
put@(n-i+1)s;
end;
put@n'*';
run;

70 bytes. Imperfect, need to assign to N handly.

data;
n=9;
do i=1to n;
s=repeat('*',i*2-2);
put@(n-i+1)s;
end;
put@n'*';
run;

The result is

        *
       ***
      *****
     *******
    *********
   ***********
  *************
 ***************
*****************
        *
\$\endgroup\$
2
  • \$\begingroup\$ Do you have a link to this language? Is there really no way to take input? \$\endgroup\$
    – Jo King
    Dec 7, 2022 at 6:51
  • \$\begingroup\$ @JoKing It is relatively rarely used. SAS is a language to do statistical analysis. \$\endgroup\$
    – whymath
    Dec 7, 2022 at 7:09
0
\$\begingroup\$

Raku, 50 48 46 bytes

(45 characters, but » is 2 bytes)

{(|^$^n,0)».&{printf "%{$n+$_}s
",\*x$_*2+1}}

Try it online!

Original 50-byte version:

-> \n{(|^n,0)».&{printf "%{n+$_}s
",'*'x 2*$_+1}}

48-byte version:

-> \n{(|^n,0)».&{printf "%{n+$_}s
",\*x$_*2+1}}
\$\endgroup\$
4
  • \$\begingroup\$ '*' can be \*, instead of -> \n you can use a placeholder parameter ($^n) and you can rarrange the 2*$_+1 to have $_ first to save that space \$\endgroup\$
    – Jo King
    Dec 7, 2022 at 7:38
  • \$\begingroup\$ @jo Thanks! But I don't think I can use a placeholder, because I'm using it inside a nested block. \$\endgroup\$
    – Mark Reed
    Dec 7, 2022 at 17:05
  • \$\begingroup\$ You can, just don't add the ^ to the second instance of $n, like {(|^$^n,0)».&{printf "%{$n+$_}s ",\*x$_*2+1}} \$\endgroup\$
    – Jo King
    Dec 7, 2022 at 20:45
  • \$\begingroup\$ Oh! Well, then. Thanks again! \$\endgroup\$
    – Mark Reed
    Dec 7, 2022 at 21:28
1 2 3
4

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.