this post was submitted on 23 Jun 2023
9 points (100.0% liked)

Code Golf

171 readers
1 users here now

Icon base by Delapouite under CC BY 3.0 with modifications to add a gradient

founded 2 years ago
MODERATORS
 

Write a function that prints an n big tree, e.g. for n=5:

     * 
    * * 
   * * * 
  * * * * 
 * * * * * 
    | |

Here is what I came up with in C:

N,i;a(n){for(i=N=N?N:n+2;i--;printf(i?"* "+(N-n-1<i):--n?"\n":"\n%*s",N,"| |"));n&&a(n);}

// the invocation isn't part of the golf:
main(){a(5);}

PS: Code blocks currently wrap around when they are too long, I've already submitted a patch to make them scroll horizontally instead.

top 13 comments
sorted by: hot top controversial new old
[–] msage 5 points 2 years ago* (last edited 2 years ago)

Perl - 55 characters with say:

say ' 'x($N-$_).'* 'x$_ for 1..$N;say ' 'x($N-2).'| |';

[–] KindaABigDyl 4 points 2 years ago (1 children)

Python - 94 chars

I tried using some alternatives, but they all ended up more verbose than:

def a(n):
 for i in range(0,n):
  print(' '*(n-i)+'* '*(i+1)+' '*(n-i-1))
 print(' '*(n-1)+'| |')

The list tools in python are great, but they all use keywords, so doing anything that doesn't directly do for and print is likely too much. You could make a list of strings for instance, and print it all out at once to save a 'print' but you'd end up using a for in list comprehension or a join or something, so you can't really save any characters afaict.

I'm sure someone will find a way to beat it tho!

[–] l4sgc 3 points 2 years ago (1 children)

Just for fun I asked ChatGPT and got a Python in 65 chars:

def p(n):print('\n'.join(' '*(n-i)+'* '*i for i in range(1,n+1)))

Since I'm most familiar with JavaScript I'll try that myself now

[–] KindaABigDyl 5 points 2 years ago* (last edited 2 years ago) (1 children)

Poor ChatGPT, it's always so close but so far. This doesn't meet spec :)

It doesn't print the bottom row of ' | | ', and it misses the leading spaces.

Fixing it produces:

def p(n):print('\n'.join(' '*(n-i)+'* '*(i+1)+' '*(n-i-1) for i in range(0,n)));print(' '*(n-1)+'| |')

Which is 102 characters, so longer than before. Like I said, I tried the list comp route. You get rid of some stuff, but you add more unfortunately.

However, both me and ChatGPT made the mistake of printing spaces after, which tbh isn't necessary. That can give a bit of a boost:

def p(n):print('\n'.join(' '*(n-i)+'* '*(i+1) for i in range(0,n)));print(' '*(n-1)+'| |')

Which is 90, but applying it to my og answer:

def a(n):
 for i in range(0,n):
  print(' '*(n-i)+'* '*(i+1))
 print(' '*(n-1)+'| |')

Yields 82.

Putting the loop on one line saves a couple characters though:

def a(n):
 for i in range(0,n):print(' '*(n-i)+'* '*(i+1))
 print(' '*(n-1)+'| |')

Gets it to 80

[–] l4sgc 4 points 2 years ago

Oh I totally missed that the trunk was part of the spec, gotta fix my own answer too

[–] xthexder 4 points 2 years ago* (last edited 2 years ago)

Here's my attempt with Rust:

101 Characters:

fn a(n:usize){for i in 1..=n{println!("{:2$}{}","","* ".repeat(i),n-i);}println!("{:1$}| |","",n-2);}

Rust Playground Link

(Edited to remove a few unnecessary whitespace characters)

[–] gamma 3 points 1 year ago

Just discovered this community existed, I've got to make a post in my usual golfing lang:

Zsh, 70 bytes

l=()
repeat $1 l=(${(l.++i.)}\* $^l' *')
print -l $l ${(l.$1-1.)}'| |'

Try it online!

The key constructs here are (l.ARITHMETIC EXPRESSION.), which left-pads, and $^l, which expands the array like a cross product. a=(a b c); echo x$a prints xa b c, but echo x$^a prints xa xb xc.

Interestingly, print -l was shorter than <<< by one byte.

[–] lyxal 2 points 2 years ago

I don't know about how y'all feel about submissions in dedicated golfing languages/esolangs like this, but

Vyxal - 14 characters/SBCS bytes (22 UTF-8 bytes)

ɾ×*vṄ| |JøĊ⁋

Vyxal is a stack-based esolang designed to do well in code-golf competitions just like this one. It's far from the only golfing language in existence, there's many more like 05AB1E, Jelly and Thunno 2. This one is just one I made in 2020 (yes creative naming I know, I just couldn't think of anything better).

You can try the program online here

Explained:

ɾ×*vṄ`| |`JøĊ⁋
ɾ               # Generate a list of numbers from 1 to the input.
 ×*             # Repeat the character "*" n many times, for each n in the above list
   vṄ           # Insert a space between each asterisk. Normally, Ṅ will join an entire list on spaces, but the v makes Ṅ apply to each item in a list.
     `| |`J     # Append the string "| |" to that list - this is the stump of the tree
           øĊ   # Centre each of the strings in the list, relative to the longest string in the list. This is a single built-in function (the ø indicates that it's a two-character function)
             ⁋  # Join the resulting list on newlines

For input = 5, the stack looks like so:

ɾ×*vṄ`| |`JøĊ⁋
ɾ                [1, 2, 3, 4, 5]
 ×*              ["*", "**", "***", "****", "*****"] (* does the multiplication, the × is the character that pushes "*" to the stack - it was a later addition)
   vṄ            ["*", "* *", "* * *", "* * * *", "* * * * *"]
     `| |`J      ["*", "* *", "* * *", "* * * *", "* * * * *", "| |"]
           øĊ    ["    *    ", "   * *   ", "  * * *  ", " * * * * ", "* * * * *", "   | |   "]
             ⁋   Output as in the original challenge post

As you can see, some built-ins automatically apply to each item in a list, as if you wrote [f(x) for x in iterable].

Once again, I don't mean to come in and ruin golf for everyone, I just want to see how such a language might be seen by the community.

[–] l4sgc 2 points 2 years ago* (last edited 2 years ago) (1 children)

My JavaScript solution - ~~82~~ 103 chars:

~~a=n=>{for(s='',i=1;i<=n;i++)s+=' '.repeat(n-i)+'* '.repeat(i)+'\n';console.log(s)}~~

a=n=>{for(s='',i=0;++i<=n;)s+=' '.repeat(n-i)+'* '.repeat(i)+'\n';console.log(s+' '.repeat(n-2)+'| |')}

I'm happy I was able to beat ChatGPT, it had the same strategy but used additional for loops instead of string.repeat(), so it was 113 chars. But I suspect further improvements might be possible with array.reduce or other prototype functions I'm forgetting about.

[–] [email protected] 3 points 2 years ago (1 children)

very cool, but you forgot the trunk

[–] l4sgc 4 points 2 years ago

Woops, can you tell my teachers were always on my case for misreading the assignment :P

[–] [email protected] 1 points 9 months ago

JavaScript, 93 characters:

l=console.log,r='repeat',b=n=>{for(i=0;i++<n;l(' '[r](n-i)+'* '[r](i)));l(' '[r](n-2)+'| |')} 
[–] Andy 0 points 1 year ago* (last edited 1 year ago)

EDIT: Damn, lemmy still mangles code. Here's a gist, and I'll replace the text in here with images.


This doesn't beat anyone's char count, but here's my try in Factor. I hope someone comes along and does it even better. 177 chars (1 line):

code screenshot 1

You prefix the number to that code to invoke.

Here it is with the slight bit of sanity afforded by line breaks and a function wrapper:

code screenshot 2

To invoke:

5 tree print 

EDIT 2: it's 176 if you replace first2 with last2, as someone pointed out to me.