Perl - 55 characters with say:
say ' 'x($N-$_).'* 'x$_ for 1..$N;say ' 'x($N-2).'| |';
Icon base by Delapouite under CC BY 3.0 with modifications to add a gradient
Perl - 55 characters with say:
say ' 'x($N-$_).'* 'x$_ for 1..$N;say ' 'x($N-2).'| |';
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!
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
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
Oh I totally missed that the trunk was part of the spec, gotta fix my own answer too
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);}
(Edited to remove a few unnecessary whitespace characters)
Just discovered this community existed, I've got to make a post in my usual golfing lang:
l=()
repeat $1 l=(${(l.++i.)}\* $^l' *')
print -l $l ${(l.$1-1.)}'| |'
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.
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.
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.
very cool, but you forgot the trunk
Woops, can you tell my teachers were always on my case for misreading the assignment :P
l=console.log,r='repeat',b=n=>{for(i=0;i++<n;l(' '[r](n-i)+'* '[r](i)));l(' '[r](n-2)+'| |')}
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):
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:
To invoke:
5 tree print
EDIT 2: it's 176 if you replace first2
with last2
, as someone pointed out to me.