# Draw an asterisk triangle

Inspired by a task for programming 101 here's a task that hopefully isn't too easy or is a duplicate (kinda hard to search for things like this).

Input:

• A positive integer n >= 1.

Output:

• n lines of asterisks, where every new line has one asterisk more than the line before, and starting with one asterisk in the first line.

General rules:

• This is code-golf, so shortest answer in bytes wins.
• Since the course is taught in C++, I'm eager to see solutions in C++.

Test case (n=5):

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

• Not duplicate, just subset of Generate a right triangle. Oct 10, 2016 at 12:20
• Training spaces allowed on each line? Oct 10, 2016 at 12:33
• Is a trailing new line acceptable? Oct 10, 2016 at 12:34
• Is a leading newline allowed? Oct 10, 2016 at 14:38
• I don't see a reason why not. Oct 11, 2016 at 11:35

# Vim, 8 bytes

o <Esc><C-V>{r*J


Takes input in the readahead buffer, so if input is 15, you would type that and then the code above. This is a silly rule, but seems to be allowed. If you got input in a register like "a, you'd just stick @a in front (10). If you got it from the start file, you'd prepend D@" instead (11).

Relies on abuse of :set autoindent, which is default in vimgolf.com rules and default in Vim 8 (and everyone uses it anyway).

• o <Esc>: With its number argument, if your text starts with whitespace, and you have :set autoindent, Vim glitches out and creates a cascade of indent.
• <C-V>{r*: Turn all those spaces into *s. I'm using block visual so that, even if your lousy indent settings silently group your spaces into tabs, you'll still get the right number of *s.
• J: Starting with o unfortunately left a blank line at the top. This removes it.
• This answer is insanely impressive. One of the coolest vim answers I've seen. Oct 11, 2016 at 13:19
• It looks like a fish. Or a rocket. Oct 12, 2016 at 11:56
• I twitched a little bit and fired Vim with -u NONE to see this by myself... It didn't work, it seems autoindent is on in the default vimrc, not vim 8 itself so I had to turn it in manually. But, hats off for the ingenuity of this answer! But why is there only one space per new line? Why does it only work with spaces but not with other characters? I still have much to learn it seems :) Oct 13, 2016 at 2:46
• Starting with O <Esc> won't require J at the end. Feb 23, 2017 at 14:29
• @udioica a single trailing newline is generally considered acceptable. Feb 24, 2017 at 22:32

# JavaScript (ES6), 31 bytes

This one includes both a leading and a trailing line-break.

We start with a string s containing only a line-break. Then we process n recursive calls, adding an asterisk on the left side of this string at each iteration. The concatenation of all intermediate strings leads to the expected result.

f=(n,s=
)=>n?s+f(n-1,'*'+s):s


Try it online!

### Without asterisk, 36 bytes

f=(n,s=
)=>n?s+f(n-1,atobKg+s):s


Try it online!

• How does it work ? Oct 10, 2016 at 13:23
• @Alexis_A - I've added a short description. Oct 10, 2016 at 13:32
• Nice recursive answer; I never would have thought of the technique you use with s. You can make it slightly less cryptic with n?s+f(n-1,'*'+s):s. Oct 10, 2016 at 14:22

# 05AB1E, 7 6 bytes

Uses CP-1252 encoding.

'*×.p»


8 byte no-asterisk version:

žQTè×.p»


Try it online!

Explanation

Example using input n = 5

'*      # push "*"
# STACK: "*"
×     # repeat input number times
# STACK: "*****"
.p   # get prefixes of string
# STACK: ['*', '**', '***', '****', '*****']
»  # join by newlines
# implicit print

• @TheBitByte 10žQSè×.p» is a logical extension of this answer to get what you wanted for the bounty and it is only 10 bytes. Give Emigna the bounty if nobody beats 10 bytes haha. Oct 13, 2016 at 20:35
• @carusocomputing: TžQè×.p» is 8 bytes even. Oct 13, 2016 at 20:41
• Still trying to learn the language, missed the T instruction; thought it was odd that there was a ton of Base2 pushes but no base 10. I have to still scour the entire contents of the info.txt to be able to do anything in that language heh. Oct 13, 2016 at 20:43
• @carusocomputing some commands are really easy to miss, especially if you know another way to do it :) Oct 13, 2016 at 20:44
• @carusocomputing: Not sure what you are referring to. The only list command I'm using here is » and that is a command specifically for merging a lists with delimiters into a string (and S would ruin that). But a lot of 05AB1E commands do vectorize, yes. Oct 14, 2016 at 13:56

# PowerShell, 21 20 bytes

1.."$args"|%{'*'*$_}


Try it online!

Loops from 1 to input $args, each iteration using string multiplication to construct a string of that many $_ asterisks. Default behavior for the implicit Write-Output at the end is with a newline for separator, so we get that for free.

PS C:\Tools\Scripts\golfing> .\draw-asterisk-pattern.ps1 5
*
**
***
****
*****

PS C:\Tools\Scripts\golfing> .\draw-asterisk-pattern.ps1 2
*
**

PS C:\Tools\Scripts\golfing> .\draw-asterisk-pattern.ps1 7
*
**
***
****
*****
******
*******


-1 byte thanks to Veskah.

• Save a byte Mar 9, 2020 at 14:03

# Python 2, 37 34 bytes

i=1;exec"print'*'*i;i+=1;"*input()


Ideone

i is initialised to 1;
then exec commands to execute the following string of code, so it must be constructed;
the string is "print'*'*i;i+=1;" but the * following the string takes precedence over the exec and instructs to first repeat the string input() times;
the exec command now executes the long string which acts like a loop, printing another string of increasing length, again using * to repeat the character '*', then incrementing i with i+=1.

Python 3, 41 bytes:
def f(n):i=1;exec("print('*'*i);i+=1;"*n); or
lambda n,i=1:exec("print('*'*i);i+=1;"*n)

# Jelly, 6 5 bytes

”*ẋþY


TryItOnline

### How?

”*ẋþY - Main link: n
”*    - literal string "*"
þ  - form outer product with the dyadic function:
ẋ   -     repeat list (right input is an implicit range(n), Jelly defaults to 1-based)
so the outer product is like:
[[i*'*' for i in range(1,len("*")+1)] for x in range(1,n+1)]
Y - join with line feeds
- implicit print


Bounty:
I'm not sure what the no ordinals clause is, since a character is a lookup of an ordinal.
Direct lookup would just be 42Ọẋþ³Y for 7 bytes - where the ³ gets us the input)
A short slightly indirect method would be, for 8 bytes, “)’Ọẋþ³Y - where we lookup ')' in jelly's code page, which is 1-indexed so “)’ yields 42.

• something interesting happens when you use a leading 0 in the input, eg. try "0414141" as an input. I'm clueless at golf languages so I wouldn't know where to begin trying to explain it.
– Luke
Oct 12, 2016 at 16:10
• I think it is evaluated as a string and hence iterates across across it as a string is an iterable and then each character evaluates to an integer as they are all digits (it will error with "hi" for example) Oct 12, 2016 at 16:20

# C#, 42 bytes

f=n=>n<1?"":f(n-1)+"\n"+new string('*',n);


Full program with test case:

using System;

namespace DrawAnAsteriskPattern
{
class Program
{
static void Main(string[] args)
{
Func<int,string>f= null;
f=n=>n<1?"":f(n-1)+"\n"+new string('*',n);

Console.WriteLine(f(5));
}
}
}

• You need it since it's a recursive function. Oct 11, 2016 at 7:29
• right. Didn't see that Oct 11, 2016 at 14:28

# Pyth, 6 bytes

j._*"*


### Explanation

j            Join by newlines
._          all prefixes of
*        the result of repeating
"*     the string "*"
as many times as the implicit input

• My first Pyth answer Oct 11, 2016 at 0:03

# GNU sed, 2524 20 + 1(n flag) = 21 bytes

Edit: 4 bytes less based on Riley's comments

x;G;:;P;s:\n.:*\n:;t


Try it online!

Run example: the input is in unary format, which for sed is allowed based on this consensus

me@LCARS:/PPCG$sed -nf draw_triangle.sed <<< "0000" * ** *** ****  A leading newline is present in the output, but this is allowed by the OP. Explanation: x;G # prepend a newline to unary string : # start loop P # print first line only s:\n.:*\n: # shift one unary char from 2nd line to 1st, converted to a '*' t # repeat  • If you Print before the substitution and a leading newline is allowed you don't need /0$/. If a newline isn't allowed you can still save a byte with x;G;:;/*/P;s:\n.:*\n:;t. I asked about a leading newline, but haven't heard back yet. Oct 10, 2016 at 14:47

# Matlab, 26 23 bytes

Good old Matlab...

@(n)tril(repmat('*',n))


Has trailing whitespaces. tril gives you the lower triangular matrix.

edit: saved 2 bythes thanks to Luis Mendo

• You are right - thanks - still not very competitive :P Oct 11, 2016 at 7:02

# C++ - 92 96 Bytes

#include<string>
int main(){int n;std::string s;scanf("%d",&n);for(;n--;)puts((s+="*").data());}


Try it online

Ungolfed:

//this one hurts, but c++ strings are mutable
#include<string>
int main(){
int n;
//this one hurts as well
std::string s;
//longer than 'std::cin>>n', but no #include<iostream> needed
scanf("%d",&n);
// same as 'while(n--)', also characterwise, but way cooler
for(;n--;)
//data() does the same as c_str()
puts((s+="*").data());
}

• should be 'int main(){}' for +4 bytes.
– user60119
Oct 14, 2016 at 20:29
• true, damn - so non-standard behaviour of gcc/ideone Oct 14, 2016 at 20:46

## Jellyfish, 1211 9 bytes

\P$'* i  Try it online! ### Explanation The above program is equivalent to the following functional pseudocode: \ P$       i        '*
map_prefixes(print, reshape(input(), '*'))


The $ (reshape) creates a string of N asterisks. \P creates a function which takes a list (or string) and passes each of its prefixes to P (print). Hence, this successively prints strings of 1 to N asterisks. ## R, 45 bytes For loop approach: for(i in 1:scan())cat(rep("*",i),"\n",sep="")  # Haskell, 35 38 bytes List comprehension thanks to nimi: f x=unlines[[1..n]>>"*"|n<-[1..x]]  Old version: f 0="" f n=f(n-1)++([1..n]>>"*")++"\n"  Alternate version: g n=([1..n]>>"*")++"\n" f n=[1..n]>>=g  • You can use ([1..n]>>"*") instead of replicate n'*' to save a byte. I also count only 39 bytes. Oct 10, 2016 at 14:06 • Nice alternate version! However I think the byte count is still of by one and should be 38. (See e.g. here) The problem might be the newline after f 0="" which is counted as one byte, but shown as two bytes/characters in some text editors. Oct 10, 2016 at 14:34 • Thanks! I see now that I was initially adding a trailing newline when I was counting the characters. Wont make that mistake again! Oct 10, 2016 at 14:39 • You can switch to a list comprehension: f x=unlines[[1..n]>>"*"|n<-[1..x]]. – nimi Oct 10, 2016 at 15:29 # Brachylog, 12 bytes yke:"*"rj@w\  Try it online! This assumes that a trailing new line is acceptable ### Explanation yk The range [0, …, Input - 1] e Take one element I of that range :"*"rj Juxtapose "*" I times to itself @w Write that string followed by a new line \ False: backtrack to another element of the range  ### No trailing new line, 15 bytes -:"*"rj:@[f~@nw  Try it online! This one works by taking all prefixes of "*" × Input. # Pyth, 7 Bytes VQ*\*hN  Knocked off a byte thanks to @ETHproductions Try it online # using @PIetu1998's Technique 6, bytes j*L*\*S  • Nice answer! You can replace "*" with \*. Oct 10, 2016 at 16:30 • @ETHproductions I never knew about that, thanks! Oct 10, 2016 at 16:35 • You can remove another byte with a map. j*L\*S (incluSive range, multiply each *L by "*" \*, join by newline) Pyth inserts an implicit Q in the end. Oct 10, 2016 at 18:19 • jm*\*h is also 6 bytes. Apr 11, 2018 at 13:13 # 2sable, 24 11 bytes >G')Ç>çJN×,  Try it online! And no sign of any asterisks! Golfed from 24 to 11 thanks to @Emigna. Explanation: >G')Ç>çJN×, > Push input+1 G For N in range (1,input+1) ')Ç>çJ Push '*' by getting ascii code for ')' and adding 1 Nx, Print '*' repeated N times  • A few tips. õVYI doesn't affect your code in any way and can be removed. 1+ is the same as >. If you create the asterisk in the loop you can also remove UX. Using × instead of the inner loop saves even more bytes. Without changing method you can get this down to 11 bytes or less. Oct 13, 2016 at 20:58 • Nice! I'll edit soon Oct 14, 2016 at 6:53 • Could you add an explanation? Oct 14, 2016 at 20:09 • Wonderful code, congrats on getting the bounty! The community bot seems to have awarded only 25 and not the original 50 I think because I forgot to award the bounty before the deadline, sorry for that. Oct 21, 2016 at 21:35 • Don't worry about it. Just glad to reach the 100-rep mark. @TheBitByte Oct 21, 2016 at 21:38 # Brain-Flak 75 Bytes Includes +3 for -A {(({})[()]<{({}[()]<(((((()()()){}()){})){}{})>)}{}((()()()()()){})>)}{}  Try it online! Explanation: {(({})[()]< >)} #reduce the top element by one until it is 0 after doing the following #Push this element back on to act as a counter for the next step. #(counts down from input to 0 we'll call this counter) {({}[()]< >)} #reduce the top element by one until it is 0 after doing the following #(counts down from counter to 0) (((((()()()){}()){})){}{}) #push 42 (the ASCII code for *) {} #pop the counter used to push #the right number of *s ((()()()()()){}) #push a 10 (newline) {} #pop the null byte  • this includes a null byte in output? I don't think that is allowed... Oct 24, 2016 at 22:55 • Nope, I mean a null byte Oct 25, 2016 at 1:22 • @DestructibleWatermelon Yeah, I guess it does. Easy fix though. Thanks. Oct 25, 2016 at 1:45 # Dyalog APL, 8 bytes ↑'*'⍴⍨¨⍳  ↑ matrify the list consisting of '*' the string "*" ⍴⍨ reshaped by ¨ each of ⍳ the integers 1 through the argument. TryAPL online! • Looks like 8 bytes to me. Jan 13, 2018 at 9:45 • if ⌸ can be a single byte: (,⍕⊢)⌸⍳ – ngn Jan 13, 2018 at 15:06 • @ngn That is very clever! Post it as your own. You may indeed count it as a single byte it you write 7 bytes<sup>SBCS</sup>. – Adám Jan 13, 2018 at 20:25 # V, 8 bytes Àé*hòlÄx  Try it online! • Oh, yes, Àé hòlÄ! Oct 10, 2016 at 12:44 • @JonathanAllan Hey, at least it's more readable than Jelly. (To me) ;) Oct 10, 2016 at 12:46 • Jelly's code page is, pretty well organised I think. Check out the overhal of the wiki's Atoms page made recently by Lynn. Oct 10, 2016 at 12:48 • @JonathanAllan Yeah, I'd believe it. It may not look like it, but V's mnemonics are well organized because of the keys you use to type them in vim. So my solution in vim-key lingo is <M-@><M-i>*h<M-r>l<M-D>x (m stands for meta, which means alt). All of those are pretty good mnemonics for what the command does. Oct 10, 2016 at 12:53 # JavaScript (ES6), 34 bytes f=x=>x?f(x-1)+ +'*'.repeat(x):''  # Perl 6, 23 bytes {.put for [\~] '*'xx$_}


( If the output is allowed to be a list of "lines" without newlines .put for  can be removed )

## Explanation:

# bare block lambda with implicit parameter ｢$_｣ { .put # print with trailing newline for # for every one of the following [\~] # produce using concatenation operator '*' xx$_ # list repeat '*' by the input
}


( See documentation for produce if you don't understand what [\~] ... is doing )

# Perl 5, 22 20 bytes

say"*"x$_ for 1..pop  Run it with the -E switch to get say. $ perl -E 'say"*"x$_ for 1..pop' 5 * ** *** **** *****  Written out as a full program it would look like this: use strict; use feature 'say'; # get the argument my$limit = pop @ARGV;

foreach my $i (1 ..$limit) {
say "*" x $i; }  • shift and pop implicitly work on @ARGV (the list of arguments) outside of subs • .. is the range operator • say includes a newline • x is an operator to repeat strings and is explained in perlop • Not sure if I need extra bytes for the command line switch. Oct 10, 2016 at 14:22 • I believe the -E flag counts as 1 extra byte. Oct 10, 2016 at 14:24 • What about taking the number as input instead of parameter? perl -E 'say"*"x$_ for 1..<>' <<< 5 Oct 10, 2016 at 15:03
• @manatwork yeah that would work. I'm not good at counting though. Not sure if that's allowed. Oct 10, 2016 at 15:11
• -E is free (as it replaces -e which would be needed anyway). If you really want to take the number from the command line (why not, even if <> is 1 byte shorter, and allowed), you should use pop instead of shift (2 bytes shorter)! Anyway, welcome on PPCG, happy to see you golfing!
Oct 10, 2016 at 15:14

## Perl, 19 bytes

-4 bytes thanks to @Ton Hospel and his rework of the solution!

eval"s//*/;say;"x<>


Needs free -E (or -M5.010) flag to run. Takes a number from input :

perl -E 'eval"s//*/;say;"x<>' <<< "5"

• You can make eval the same length as the for solution (using <> instead of pop) with eval"s//*/;say;"x<> Oct 10, 2016 at 17:19
• @TonHospel Ineed, nice! thanks!
Oct 10, 2016 at 19:20

# J, 11 8 bytes

Saved 3 bytes thanks to miles!

]\@#&'*'


Here is a decomposition:

(]\@#&'*') x
x (]\@#) '*'
]\ (x # '*')


Now, this last one reads as "the prefixes (]\) of the string consisting of x copies of '*'". Observe:

   5 ]\@# '*'
*
**
***
****
*****
]\ 5# '*'
*
**
***
****
*****
]\ 5 # '*'
*
**
***
****
*****
]\@#&'*' 5
*
**
***
****
*****


## Test case

   f =: ]\@#&'*'
f 3
*
**
***
f 5
*
**
***
****
*****
f 1
*
f 2
*
**
f &. > ;/1+i.10
+-+--+---+----+-----+------+-------+--------+---------+----------+
|*|* |*  |*   |*    |*     |*      |*       |*        |*         |
| |**|** |**  |**   |**    |**     |**      |**       |**        |
| |  |***|*** |***  |***   |***    |***     |***      |***       |
| |  |   |****|**** |****  |****   |****    |****     |****      |
| |  |   |    |*****|***** |*****  |*****   |*****    |*****     |
| |  |   |    |     |******|****** |******  |******   |******    |
| |  |   |    |     |      |*******|******* |*******  |*******   |
| |  |   |    |     |      |       |********|******** |********  |
| |  |   |    |     |      |       |        |*********|********* |
| |  |   |    |     |      |       |        |         |**********|
+-+--+---+----+-----+------+-------+--------+---------+----------+


## Older, 11-byte solutions

'*'#~"+1+i.


This is equivalent

'*' #~"0 1 + i.


1 + i. is the range [1, x]. Then, '*' #~"0 applied to this range shapes (element) copies of '*'.

Bonus program:

[:#&'*'\#&1


This is a capped fork #&'*'\ applied to the result of #&1 of the input. #&1 gives an array of x ones, and #&'*'\ shapes '*' to the prefixes of this array.

### Test cases

   f1 =: '*'#~"+1+i.
f2 =: [:#&'*'\#&1
f1 1
*
f2 2
*
**
f1 3
*
**
***
f2 4
*
**
***
****
f2 5
*
**
***
****
*****
f1 5
*
**
***
****
*****
(f1;f2)3
+---+---+
|*  |*  |
|** |** |
|***|***|
+---+---+
f1;f2
f1 ; f2
(f1;f2)5
+-----+-----+
|*    |*    |
|**   |**   |
|***  |***  |
|**** |**** |
|*****|*****|
+-----+-----+
(f1;f2)10
+----------+----------+
|*         |*         |
|**        |**        |
|***       |***       |
|****      |****      |
|*****     |*****     |
|******    |******    |
|*******   |*******   |
|********  |********  |
|********* |********* |
|**********|**********|
+----------+----------+

• You could also get the prefixes of the string of n copies of '*' for 8 bytes using ]\@#&'*' Oct 11, 2016 at 4:08
• @miles: and another 9 byte version: '*'"0\@i. Sep 17, 2017 at 17:43

# Vim, 22, 18 keystrokes

O <esc>J:h r<cr>lyEZZ<C-v>{@"


Huge credit to @Udioica for coming up with an awesome vim answer that I expanded on. This answer does not contain any asterisks, in hopes of winning the bounty.

Explanation:

Input is typed before the rest of the program. Udioica came up with this awesome trick. Typing <n>O <esc> will create a pyramid of spaces and one empty line, as long as you have :set autoindent enabled. This option comes on by default in vim 8 and neovim, though not older versions of vim. Since this also creates an extra line, we use J to join this line with the next one, which effectively just removes the line below us.

Now at this point, we need to replace all of these spaces with asterisks. If I was not worried about using asterisks in my code, I would just visually select the whole thing <C-v>{ and type r*, which replaces each character of the selection with an asterisk. But I can't do that.

So we open up the help pages to :h r. The interesting thing about this is that in the vim-window, this page is displayed as:

                            r
r{char}         Replace the character under the cursor with {char}.
...


With the cursor on the first 'r'. However, the file itself actually contains this text:

                            *r*
r{char}         Replace the character under the cursor with {char}.
...


Pretty convenient. So we move over one character with l, and yank the text r* with yE ([y]ank to the [E]nd of this word).

To close this buffer, we use the shortcut to save a file ZZ. Now, we visually select our spaces, and run the yanked text as if we had typed it by doing @". This works because "@" runs the following register as vim-keystrokes, and " is the default register for yanking.

• Care to explain how it works? Oct 16, 2016 at 19:05
• @corvus_192 I have added a more extensive explanation, as well as golfing some more off. Oct 17, 2016 at 1:40
• Shouldn't the size of the data file be added to the byte count? Oct 17, 2016 at 8:50
• @aross the size of the help file? No, because this file is installed alongside vim, and is a default feature. Oct 17, 2016 at 11:48

# C, 474645 43 bytes

Takes input from the command line

f(n){for(n&&f(n-1);~n;putchar(n--?42:10));}


Basically if n is not 0 recurse on n-1. at the top of the recursion where n is 0 it just prints a newline, the for loop terminates when n is -1 or ~n is zero, otherwise it prints ASCII 42 which is '*'. Try it on ideone

# C++ 58 Bytes + 19 for including iostream is 77

#include<iostream>
int f(int n){for(n&&f(n-1);~n;std::cout<<(n--?"*":"\n"));}


main(c,v)char**v;
{
f(atoi(v[1]));
}


a.exe 3
*
**
***

• To me seems to work with &&: n?f(n-1):0n&&f(n-1). Oct 11, 2016 at 17:07
• @manatwork Thanks bud. saving another byte Oct 11, 2016 at 18:53
• In ideone the print of 2 triangle show at the end there is one '\n' more: * ** *** * ** *** **** ***** I say the case 0 the case end of revursion, print one \n more
– user58988
Oct 11, 2016 at 22:32
• @RosLup Yes it's printing a leading and a trailing newline. I think the OP said that was OK in his comments. Oct 12, 2016 at 13:21

## Retina, 14 bytes

Byte count assumes ISO 8859-1 encoding.

.+
$** .$$&¶  Try it online! ### Explanation .+$**


Turn the input N into N asterisks.

.
$$&¶


Replace each asterisk with everything up to and including that asterisk (this is the $$&) and a linefeed (this the ¶).

# MATL, 9 8 bytes

1 byte saved thanks to @Luis

:"42@Y"c


Try it Online

# Cubix, 22 bytes

?(.;I:^;/-.@o;(!\>'*oN


Test it online! Outputs a trailing newline.

At first I wasn't sure I could get this to fit on a 2-cube, but in the end it worked out fine:

    ? (
. ;
I : ^ ; / - . @
o ; ( ! \ > ' *
o N
. .
`

I'll add an explanation when I have time, hopefully later today.

• Explanation anytime soon? :P Dec 28, 2017 at 23:27