64
\$\begingroup\$

Inspired by a task for Programming 101, here's a challenge that hopefully isn't too easy (or a duplicate).

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.

Test case (n=5):

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

This is , so shortest answer in bytes wins.

\$\endgroup\$
10
  • 7
    \$\begingroup\$ Not duplicate, just subset of Generate a right triangle. \$\endgroup\$
    – manatwork
    Oct 10, 2016 at 12:20
  • 2
    \$\begingroup\$ Training spaces allowed on each line? \$\endgroup\$
    – Luis Mendo
    Oct 10, 2016 at 12:33
  • 2
    \$\begingroup\$ Is a trailing new line acceptable? \$\endgroup\$
    – Fatalize
    Oct 10, 2016 at 12:34
  • 1
    \$\begingroup\$ Is a leading newline allowed? \$\endgroup\$
    – Riley
    Oct 10, 2016 at 14:38
  • \$\begingroup\$ I don't see a reason why not. \$\endgroup\$
    – Sickboy
    Oct 11, 2016 at 11:35

153 Answers 153

1
2 3 4 5 6
44
+500
\$\begingroup\$

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.
\$\endgroup\$
7
  • 1
    \$\begingroup\$ This answer is insanely impressive. One of the coolest vim answers I've seen. \$\endgroup\$
    – DJMcMayhem
    Oct 11, 2016 at 13:19
  • 1
    \$\begingroup\$ It looks like a fish. Or a rocket. \$\endgroup\$ Oct 12, 2016 at 11:56
  • 1
    \$\begingroup\$ 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 :) \$\endgroup\$ Oct 13, 2016 at 2:46
  • \$\begingroup\$ Starting with O <Esc> won't require J at the end. \$\endgroup\$
    – primo
    Feb 23, 2017 at 14:29
  • 1
    \$\begingroup\$ @udioica a single trailing newline is generally considered acceptable. \$\endgroup\$
    – primo
    Feb 24, 2017 at 22:32
24
\$\begingroup\$

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,atob`Kg`+s):s

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ How does it work ? \$\endgroup\$
    – Alexis_A
    Oct 10, 2016 at 13:23
  • 1
    \$\begingroup\$ @Alexis_A - I've added a short description. \$\endgroup\$
    – Arnauld
    Oct 10, 2016 at 13:32
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Oct 10, 2016 at 14:22
19
\$\begingroup\$

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
\$\endgroup\$
14
  • \$\begingroup\$ @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. \$\endgroup\$ Oct 13, 2016 at 20:35
  • 1
    \$\begingroup\$ @carusocomputing: TžQè×.p» is 8 bytes even. \$\endgroup\$
    – Emigna
    Oct 13, 2016 at 20:41
  • \$\begingroup\$ 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. \$\endgroup\$ Oct 13, 2016 at 20:43
  • \$\begingroup\$ @carusocomputing some commands are really easy to miss, especially if you know another way to do it :) \$\endgroup\$
    – Emigna
    Oct 13, 2016 at 20:44
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – Emigna
    Oct 14, 2016 at 13:56
15
\$\begingroup\$

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.

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

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)

\$\endgroup\$
13
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$
    – Luke
    Oct 12, 2016 at 16:10
  • \$\begingroup\$ 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) \$\endgroup\$ Oct 12, 2016 at 16:20
11
\$\begingroup\$

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));
        }
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ You need it since it's a recursive function. \$\endgroup\$
    – adrianmp
    Oct 11, 2016 at 7:29
  • \$\begingroup\$ right. Didn't see that \$\endgroup\$
    – Cyoce
    Oct 11, 2016 at 14:28
10
\$\begingroup\$

Pyth, 6 bytes

j._*"*

Try it here.

Explanation

j            Join by newlines
 ._          all prefixes of
    *        the result of repeating
      "*     the string "*"
             as many times as the implicit input 
\$\endgroup\$
1
  • 3
    \$\begingroup\$ My first Pyth answer \$\endgroup\$
    – Luis Mendo
    Oct 11, 2016 at 0:03
10
\$\begingroup\$

GNU sed, 25 24 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
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – Riley
    Oct 10, 2016 at 14:47
8
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ You are right - thanks - still not very competitive :P \$\endgroup\$
    – mathause
    Oct 11, 2016 at 7:02
8
\$\begingroup\$

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; 
    //read input to n
    //longer than 'std::cin>>n', but no #include<iostream> needed
    scanf("%d",&n); 
    // same as 'while(n--)', also characterwise, but way cooler
    for(;n--;) 
        //add a '*' the string
        //data() does the same as c_str()
        //puts automatically adds an '\n'
        puts((s+="*").data()); 
}
\$\endgroup\$
2
  • \$\begingroup\$ should be 'int main(){}' for +4 bytes. \$\endgroup\$
    – user60119
    Oct 14, 2016 at 20:29
  • \$\begingroup\$ true, damn - so non-standard behaviour of gcc/ideone \$\endgroup\$
    – Anedar
    Oct 14, 2016 at 20:46
7
\$\begingroup\$

Jellyfish, 12 11 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.

\$\endgroup\$
7
\$\begingroup\$

R, 45 bytes

For loop approach:

for(i in 1:scan())cat(rep("*",i),"\n",sep="")
\$\endgroup\$
7
\$\begingroup\$

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
\$\endgroup\$
4
  • \$\begingroup\$ You can use ([1..n]>>"*") instead of replicate n'*' to save a byte. I also count only 39 bytes. \$\endgroup\$
    – Laikoni
    Oct 10, 2016 at 14:06
  • \$\begingroup\$ 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. \$\endgroup\$
    – Laikoni
    Oct 10, 2016 at 14:34
  • \$\begingroup\$ Thanks! I see now that I was initially adding a trailing newline when I was counting the characters. Wont make that mistake again! \$\endgroup\$
    – Craig Roy
    Oct 10, 2016 at 14:39
  • 2
    \$\begingroup\$ You can switch to a list comprehension: f x=unlines[[1..n]>>"*"|n<-[1..x]]. \$\endgroup\$
    – nimi
    Oct 10, 2016 at 15:29
6
\$\begingroup\$

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.

\$\endgroup\$
6
\$\begingroup\$

Pyth, 7 Bytes

VQ*\*hN

Knocked off a byte thanks to @ETHproductions Try it online

using @PIetu1998's Technique

6, bytes

j*L*\*S
\$\endgroup\$
4
  • \$\begingroup\$ Nice answer! You can replace "*" with \*. \$\endgroup\$ Oct 10, 2016 at 16:30
  • \$\begingroup\$ @ETHproductions I never knew about that, thanks! \$\endgroup\$ Oct 10, 2016 at 16:35
  • \$\begingroup\$ 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. \$\endgroup\$ Oct 10, 2016 at 18:19
  • \$\begingroup\$ jm*\*h is also 6 bytes. \$\endgroup\$
    – hakr14
    Apr 11, 2018 at 13:13
6
+25
\$\begingroup\$

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
\$\endgroup\$
5
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Emigna
    Oct 13, 2016 at 20:58
  • 1
    \$\begingroup\$ Nice! I'll edit soon \$\endgroup\$ Oct 14, 2016 at 6:53
  • \$\begingroup\$ Could you add an explanation? \$\endgroup\$ Oct 14, 2016 at 20:09
  • \$\begingroup\$ 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. \$\endgroup\$ Oct 21, 2016 at 21:35
  • 1
    \$\begingroup\$ Don't worry about it. Just glad to reach the 100-rep mark. @TheBitByte \$\endgroup\$ Oct 21, 2016 at 21:38
6
\$\begingroup\$

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
\$\endgroup\$
3
  • \$\begingroup\$ this includes a null byte in output? I don't think that is allowed... \$\endgroup\$ Oct 24, 2016 at 22:55
  • \$\begingroup\$ Nope, I mean a null byte \$\endgroup\$ Oct 25, 2016 at 1:22
  • \$\begingroup\$ @DestructibleWatermelon Yeah, I guess it does. Easy fix though. Thanks. \$\endgroup\$
    – Riley
    Oct 25, 2016 at 1:45
6
\$\begingroup\$

Dyalog APL, 8 bytes

↑'*'⍴⍨¨⍳

matrify the list consisting of

'*' the string "*"

⍴⍨ reshaped by

¨ each of

the integers 1 through the argument.

TryAPL online!

\$\endgroup\$
3
  • \$\begingroup\$ Looks like 8 bytes to me. \$\endgroup\$ Jan 13, 2018 at 9:45
  • 1
    \$\begingroup\$ if can be a single byte: (,⍕⊢)⌸⍳ \$\endgroup\$
    – ngn
    Jan 13, 2018 at 15:06
  • \$\begingroup\$ @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>. \$\endgroup\$
    – Adám
    Jan 13, 2018 at 20:25
5
\$\begingroup\$

V, 8 bytes

Àé*hòlÄx

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Oh, yes, Àé hòlÄ! \$\endgroup\$ Oct 10, 2016 at 12:44
  • 2
    \$\begingroup\$ @JonathanAllan Hey, at least it's more readable than Jelly. (To me) ;) \$\endgroup\$
    – DJMcMayhem
    Oct 10, 2016 at 12:46
  • \$\begingroup\$ Jelly's code page is, pretty well organised I think. Check out the overhal of the wiki's Atoms page made recently by Lynn. \$\endgroup\$ Oct 10, 2016 at 12:48
  • 3
    \$\begingroup\$ @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. \$\endgroup\$
    – DJMcMayhem
    Oct 10, 2016 at 12:53
5
\$\begingroup\$

JavaScript (ES6), 34 bytes

f=x=>x?f(x-1)+`
`+'*'.repeat(x):''
\$\endgroup\$
5
\$\begingroup\$

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 )

\$\endgroup\$
5
\$\begingroup\$

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
\$\endgroup\$
6
  • \$\begingroup\$ Not sure if I need extra bytes for the command line switch. \$\endgroup\$
    – simbabque
    Oct 10, 2016 at 14:22
  • \$\begingroup\$ I believe the -E flag counts as 1 extra byte. \$\endgroup\$ Oct 10, 2016 at 14:24
  • \$\begingroup\$ What about taking the number as input instead of parameter? perl -E 'say"*"x$_ for 1..<>' <<< 5 \$\endgroup\$
    – manatwork
    Oct 10, 2016 at 15:03
  • \$\begingroup\$ @manatwork yeah that would work. I'm not good at counting though. Not sure if that's allowed. \$\endgroup\$
    – simbabque
    Oct 10, 2016 at 15:11
  • 1
    \$\begingroup\$ -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! \$\endgroup\$
    – Dada
    Oct 10, 2016 at 15:14
5
\$\begingroup\$

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"
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can make eval the same length as the for solution (using <> instead of pop) with eval"s//*/;say;"x<> \$\endgroup\$
    – Ton Hospel
    Oct 10, 2016 at 17:19
  • \$\begingroup\$ @TonHospel Ineed, nice! thanks! \$\endgroup\$
    – Dada
    Oct 10, 2016 at 19:20
5
\$\begingroup\$

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
+----------+----------+
|*         |*         |
|**        |**        |
|***       |***       |
|****      |****      |
|*****     |*****     |
|******    |******    |
|*******   |*******   |
|********  |********  |
|********* |********* |
|**********|**********|
+----------+----------+
\$\endgroup\$
2
  • \$\begingroup\$ You could also get the prefixes of the string of n copies of '*' for 8 bytes using ]\@#&'*' \$\endgroup\$
    – miles
    Oct 11, 2016 at 4:08
  • \$\begingroup\$ @miles: and another 9 byte version: '*'"0\@i. \$\endgroup\$
    – Jonah
    Sep 17, 2017 at 17:43
5
\$\begingroup\$

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.

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

C, 47 46 45 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
*
**
***
\$\endgroup\$
4
  • \$\begingroup\$ To me seems to work with &&: n?f(n-1):0n&&f(n-1). \$\endgroup\$
    – manatwork
    Oct 11, 2016 at 17:07
  • \$\begingroup\$ @manatwork Thanks bud. saving another byte \$\endgroup\$
    – cleblanc
    Oct 11, 2016 at 18:53
  • \$\begingroup\$ 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 \$\endgroup\$
    – user58988
    Oct 11, 2016 at 22:32
  • \$\begingroup\$ @RosLup Yes it's printing a leading and a trailing newline. I think the OP said that was OK in his comments. \$\endgroup\$
    – cleblanc
    Oct 12, 2016 at 13:21
5
\$\begingroup\$

Commodore 64/VIC-20 BASIC (and compatible C= 8-bits), ~77 tokenized BASIC bytes

0 INPUT"NUMBER OF *";A:ON-(A<1)GOTO1:J=1:FORI=1TOA:FORX=1TOJ:PRINT"*";:NEXTX:J=J+1:PRINT:NEXTI
1 :

Technically line 1 isn't required, but I'm mis-using the ON...GOTO command as a conditional GOTO in line zero so I added in the shortest possible line 1 to end it gracefully.

You will need to use Commodore keyword abbreviations to fit line zero on a C64, see the screen shot below (Note that the C128 in 128 mode might have different keyword abbreviations, but then you can enter more characters so you probably won't need it):

Commodore 64 asterisk printing simulator

\$\endgroup\$
4
\$\begingroup\$

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

\$\endgroup\$
4
\$\begingroup\$

MATL, 9 8 bytes

1 byte saved thanks to @Luis

:"42@Y"c

Try it Online

\$\endgroup\$
0
1
2 3 4 5 6

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.