62
\$\begingroup\$

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

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

150 Answers 150

1 2 3 4
5
1
\$\begingroup\$

Scala, 44 30 bytes (51 45 without asterisk, 41 for hourglass)

With asterisk in code (30 bytes):

(i:Int)=>(i to(1,-1))map("*"*) //create a range from i to 1 and map each number to that number of asterisks

Without asterisk (45 bytes):

(i:Int)=>(i to(1,-1))map(((41+1).toChar+"")*) //same as above, but without a literal asterisk

Without asterisk and easy ways of calculating 42 (57 bytes):

(i:Int)=>(i to(1,-1))map(((math sqrt("7G"##)).toChar+"")*)

## is the hashcode method, which returns 1764 for the string "7G", the square root of 1764 is 42, the ascii code for *

Hourglass:

(& :Int)=>((&to(1,-1))++(2 to&))map("*"*)

(& :Int)=>        //define an anonymus function with an int parameter called &
  (              
    (& to (1,-1))   //a range from & to 1, counting by -1, aka downwards
    ++              //concat
    (2 to&)         //a range from 2 to &
  )
  map(              //map each number to
    "*" *             //the string "*" repeated x times
  )
\$\endgroup\$
5
  • 1
    \$\begingroup\$ @TheBitByte You're right, I didn't notice that I've used asterisks for multiplication / string repitition. I just thought that I could replace '*' with (7*6).toChar and that's it. \$\endgroup\$
    – corvus_192
    Oct 14 '16 at 14:50
  • 1
    \$\begingroup\$ The bounty spec is not really precise, it just states "other cheating methods". I have no idea what you consider cheating. \$\endgroup\$
    – corvus_192
    Oct 16 '16 at 18:15
  • 1
    \$\begingroup\$ @TheBitByte What do you consider acceptable then? sqrt(1764)? Building a sequence of 42 ones and summing them? Using a string used somewhere in the standard library and extract an asterisk from it? \$\endgroup\$
    – corvus_192
    Oct 16 '16 at 18:39
  • 1
    \$\begingroup\$ @TheBitByte It's your bounty, you can make the rules but you should precisely state what you allow and what you consider cheating. \$\endgroup\$
    – corvus_192
    Oct 16 '16 at 19:02
  • 1
    \$\begingroup\$ @TheBitByte I know that scala can't win against all those golfing languages \$\endgroup\$
    – corvus_192
    Oct 16 '16 at 19:14
1
\$\begingroup\$

Element, 16 bytes

_'[1+'[\*`]\
`"]

Try it online!

Explanation:

This is a pretty simple nested-loop approach. Let N represent the newline in the source code.

_'[1+'[\*`]\N`"]
_'                take input and move it to the control stack
  [            ]  a FOR loop, each iteration = 1 line of output
  [1+          ]  increment the top of the stack, as a counter
  [  '         ]  move that value to the control stack
  [   [   ]    ]  another FOR loop, for the current line
  [   [\*`]    ]  output a literal asterisk
  [        \N` ]  output a literal newline
  [           "]  move the counter from control to main stack
\$\endgroup\$
1
\$\begingroup\$

C++, 63 bytes

void s(int n){if(n)s(n-1),cout<<setfill('*')<<setw(n+1)<<"\n";}

Usage:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    s(5);
}

Overrides the filling character (which is usually a space), and outputs an empty string (or actually a newline).

One weird thing about this code is the usage of if (...) - I cannot find a way to replace it by a conditional operator ... ? ... : ....

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

Swift 3, 86 bytes

for i in 1...Int(CommandLine.arguments[1])!{print(String(repeatElement("*",count:i)))}

Yuck. If I can drop the Int and String initializers I might be able to get this shorter than Java. Open to any optimizations.

Ungolfed:

import Foundation

guard CommandLine.argc > 1, let a = Int(CommandLine.arguments[1]) else {
    fatalError("Invalid or nonexistent argument")
}

for i in 1...a {
    print(String(repeatElement("*", count: i)))
}

Usage:

➜ ~ swift asterisk.swift 5
*
**
***
****
*****
\$\endgroup\$
1
\$\begingroup\$

><>, 47 bytes

<v[1:$-1;!?:$+10
0\:&
$>:@=?v1+&:&"*"o
0f]oa~<.

Try it here!

This was fun to write, though a bit more bytes than I expected.

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

Sinclair ZX81/Timex TS1000/1500, 117 bytes (listing)

1 PRINT "NUMBER OF * TO SHOW?"
2 INPUT A
3 IF A<1 THEN STOP
4 LET J=A/A
5 FOR I=1 TO A
6 FOR X=1 TO J
7 PRINT "*";
8 NEXT X
9 LET J=J+1
10 PRINT
11 NEXT I

Note that because the screen scroll isn't handled in this program listing, you may only enter a number between 0 and 22 because as soon as the ZX81 hits the bottom of the screen it will halt the program. You can see the missing * by using CONT when this happens, but also note that the ZX81 only has 32 columns text by default in BASIC.

\$\endgroup\$
1
  • \$\begingroup\$ To save actual (system) bytes, you may amend the following lines: 3 IF A<CODE "{GRAPHICS ON}{SHIFT}1{SHIFT OFF}{GRAPHICS OFF}" 5 FOR I=PI/PI TO A 6 FOR X=PI/PI TO J 9 LET J=J+PI/PI \$\endgroup\$ Feb 27 '17 at 9:42
1
\$\begingroup\$

SQL, 80 bytes

DECLARE @i INT=1,@ INT=5WHILE @i<>@ BEGIN PRINT REPLICATE('*',@i)SET @i=@i+1 END

ungolfed:

DECLARE @index INT=1, 
        @rows INT=5

WHILE @index<>@rows 
BEGIN 
    PRINT REPLICATE('*',@index)
    SET @index=@index+1 
END
\$\endgroup\$
1
\$\begingroup\$

Rebol, 32 bytes

loop do input[print append{}"*"]

Ungolfed:

loop do input [
    print append {} "*"
]
\$\endgroup\$
1
\$\begingroup\$

AutoHotkey, 28 bytes

Loop,%1%
Send,{* %A_Index%}`n

%1% is the first argument passed in
%A_Index% is the current iteration in the loop
Send sends a keystroke multiple times if it's followed by a number

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

dc, 33 bytes

?sa0[1+d1F6r^3C*1EF/PAPdla>x]dsxx

Input on stdin, output on stdout.

Try it online!

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

Forte, 101 bytes

1INPUT0
2LET4=(0*(0+1))*5
4END
6PUT42:LET7=6+1
7LET6=6+10
8PUT10:LET9=((9+9)+14)-3:LET3=8+5
3LET8=9-1

Try it online!

I've been wanting to try Forte for a while, and this seemed like a fine challenge for it. It was quite an effort writing the program, then golfing it and making it fit in one-digit numbered lines. It was also quite fun :) Kudos to ais523 for inventing this and many more incredible languages.

Since I'm in the mood I'll write an explanation in details, covering also the basis of the language.

Explanation

First, a very brief introduction for those who don't know this language, you can find the full specification and guide on its esolang page.

The syntax of Forte is similar BASIC, with line numbers prepended to each line, only that in Forte you dont GOTO 10, you make 10 come to you!

With the command LET, you can assign a number to... another number. If the command LET 10=20 is executed, from now on every time the number 10 is referenced, directly or indirectly (5+5 counts too), it is replaced by 20 instead. This affects line numbers too, so if we were on line 19 when executing that instruction, the next line to be executed will be our old line 10, now line 20.

Now, the actual code (with spaces added for clarity):

1 INPUT 0

This is practically LET 0=<a number taken from stdin>, in this program 0 is used like a variable, and only in line number 2

2 LET 4=(0*(0+1))*5
4 END

Line 4 is the one that terminates the program, so we want to put it at the position where we are done printing asterisks. How many of them do we need to print, though? As fitting for a "draw a triangle" challenge, the answer is given by triangular numbers!

The formula to calculate the nth triangular number is n*(n+1)/2. We will print an asterisk every 10 lines, so we multiply it by 10 and get n*(n+1)*5. Use 0 instead of n, add parentheses for every operation (always mandatory in Forte), and you get line 2.

6 PUT 42:LET 7=6+1
7 LET 6=6+10

Here we print the asterisks. The ASCII code for * is 42, so you get what PUT 42 does. The colon separates multiple instructions on the same line, so we then execute LET 7=6+1. What use do we have in redefining 7 as 6+1? Isn't it the same thing? Let's see what happens next.

Line 7 redefines 6 as 6+10, so 16. Ignoring for a moment the rest of the code, this means that when we reach line 16 we will print another asterisk, and then redefine 7 as 6+1. But now 6 is 16, so we are redefining it as 16+1! Line 7 is now line 17 and is the next one to be executed, changing 6 to 6+10, which means changing 16 to 16+10, so on line 26 we will print another asterisk, and so on.

Since in Forte a line cannot change its own number, this is the simplest structure for a loop, two lines changing each other's numbers repeatedly. I know this can be quite confusing, but that's kind of the point of the whole language ;)

8 PUT 10:LET 9=((9+9)+14)-3:LET 3=8+5
3 LET 8=9-1

Ok, that line 3 put here may seem out of place, but in Forte line order doesn't matter, only line numbering. I've chosen to put this line at the end because this pair of lines forms again a cycle, redefining each other's numbers, so it's easier to see them together. Moreover, the first time line 3 is executed (when 3 is still equal to 3 and nothing else), it has no effect on the program, redefining 8 as 8.

As you probably have guessed PUT 10 prints a newline, then the hard part comes. We want each line to have one more asterisk than the one before, so to know where to put the next newline we need to know where the previous one was. To do this, we use another "variable": the number 9. In practice, when we are about to print a newline on line 8, line 3 will be positioned (near) where the previous newline was printed, we'll use it to calculate where the next newline must be printed and move 9 (near) there. (Remember that line 8 can't move itself). Then we move line 3 a bit further than the current position, and use it to move line 8 to our 9.

These three numbers (3,8, and 9) were chosen in order not to conflict with any other redefinition of a number, and to be easy to use together (since neither 5 nor 1 will ever be redefined by this program we can do LET 3=8+5 and LET 8=9-1).

All of these numbers will always be redefined as themselves+10n. This means that 8 will only ever be redefined to numbers ending with an 8 (28,58,98...). This same property is valid for any other number redefinintion in this program (except 0), because this helped greatly my reasoning while writing the code (if you are crazy enough you can try to golf some bytes by using a smaller step, but I doubt there is much room for golfing without completely changing approach).

So, the actual difficult part of this program: LET 9=((9+9)+14)-3. This operation can be better explained if expanded to LET 9=(9+(9-(3-4)))+10, where 4 and 10 represent their respective actual numerical values (in the code they are grouped as 14, 4 wouldn't actually be usable because it was redefined in line 2). As we said before 3 is still placed near the previous newline; we subtract 4 from it to get the previous position of 9 (if 3 is 63, our previous 9 was 59), then we compute the difference between the current and the previous 9 to know how many program-lines have passed since the last newline was printed. We add this value to the current 9, plus 10 because the next time we will want to print one more asterisk. Our 9 is now where we want to print the next newline, so we move 3 to the current position, it will then move 8 to where it's needed, just before 9.

Phew, that was long. And hard. No dirty jokes, please

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

Perl 6 (27)

{.say for '*' <<x<<(1..$_)}
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 44 bytes

n=>[...Array(n)].map(_=>s+="*",s="").join`
`

If outputting as an array is permitted then subtract 8 bytes.

n=>[...Array(n)].map(_=>s+="*",s="")

Try it

f=
n=>[...Array(n)].map(_=>s+="*",s="").join`
`
oninput=_=>o.innerText=f(+i.value)
o.innerText=f(i.value=5)
<input id=i min=1 type=number><pre id=o>

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

tcl, 39

time {puts [string repe * [incr i]]} $n

demo

tcl, 46

while {[incr i]<=$n} {puts [string repe * $i]}

demo

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

RProgN 2, 5 bytes

²`**S

Outputs a stack of strings.

Explained

²`**S
²       # Define the function with the next two concepts, `* and * in this case.
    S   # Create a stack from 1 to the input, and execute the previous function on each element.
   *    # Multiply the element by
 `*     # The string "*", which repeats it. Output is implicit.

Try it online!

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

8th, 38 bytes

Code

( ( "*" . ) swap times cr ) 1 rot loop

SED (Stack Effect Diagram) is: n --

Example

ok> 5 ( ( "*" . ) swap times cr ) 1 rot loop
*
**
***
****
*****
\$\endgroup\$
1
\$\begingroup\$

Excel VBA, 37 Bytes

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

[B1].Resize([A1])="=Rept(""*"",Row())
\$\endgroup\$
1
\$\begingroup\$

J, 11 Bytes

$&'*'@>:@i.

Includes trialing spaces on every line.

Explanation:

$&'*'@>:@i.    | Full program
     @  @      | Verb conjunction characters, make sure it isn't executed as a hook
         i.    | Integers 0 to n-1
      >:       | Increment (Integers 1 to n)
$&'*'          | Reshape the array '*' to the size of each item by repeating it cyclically

Note that normally the dyadic ranks of $ are 1 _, so that $&'*' 1 2 3 would create a 1 by 2 by 3 array of '*'s. However, the @ cunjunction ensures that $&'*' is applied to each cell of it's argument.

\$\endgroup\$
3
1
\$\begingroup\$

Julia 0.6, 13 bytes

n->"*".^(1:n)

^ is used for exponentiation and string repeating in Julia. This follows from the choice of '*' for string concatenation, which was chosen over '+' because addition is supposed to be commutative, and string concatenation is not. A function or operator preceded by . is "broadcasted", which in this case mean it is applied elementwise.

Outputs an array of strings. Depending on how the rules are interpreted it may need println.("*".^(1:n)) (23 bytes, meets any interpretation) or display("*".^(1:n)) (22 bytes, prints exact desired output plus an additional line about the array type) or "*".^(1:x).*"\n" (19 bytes, array of strings with newlines). Example of each in TIO.

Try it online!

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

Windows batch, 69 bytes

@set v=
@for /l %%G in (1,1,%1)do @call set v=*%%v%%&call echo %%v%%

Just putting an extra asterisk after each line.

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

Pyt, 17 bytes

←ř↔0⇹Á`⑴67**Ƈǰƥłŕ

Explanation:

←                             Get input
 ř↔                           Push [input,input-1,...,1] onto stack
   0⇹                         Push 0, and flip the top two items on the stack
     Á                        Push contents of array onto stack
      `         ł             While top of stack is not 0, loop:
       ⑴                     Create an array of 1s with length equal to the top of the stack
         67**                 Multiply each element in the array by 42
             Ƈǰƥ              Convert to ASCII, join, and print; if top of stack is 0, exit loop
                 ŕ            Pop the 0

Try it online!

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

brainfuck, 42 bytes

++++++++++<<,[>>[>]>--[<+>++++++]<-[.<]<-]

Try it online!

Takes the number as the char code of the input. Add two to avoid using negative cells, four to avoid wrapping.

How It Works:

Tape Format:  Input 0 10 * * * *...
++++++++++ Creates the newline cell
<<, Gets input
[ While input
 >>[>] Go to the end of the line of asterisks
 >--[<+>++++++]<- Add an asterisk to the end of the line
 [.<] Print the line including the newline
 <- Subtract one from the input
]
\$\endgroup\$
1
\$\begingroup\$

Stax, 4 bytes

m'**

Run and debug it

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

Japt -R, 4 bytes

õç'*

Try it here

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

Noether, 14 bytes

I("*"i1+*P?!i)

Try it online

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

Keg, -pn, 8 bytes

Ï^⑷`*`*,

Try it online!

Explanation

Ï^

In the first part of the program, we push a range from 0 to n onto the stack. Then we reverse it because otherwise, the triangle is upside down.

We then start a mapping to the entire stack with the following:

    `*`*,

Which says to multiply the string * by the number being mapped and print it.

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

Erlang (escript), 50 bytes

s(0)->"";s(N)->s(N-1)++string:copies("*",N)++"~n".

Try it online!

Explanation

s(0)->"";    % If the current item is 0, return the empty string.
s(N)->       % Otherwise:
s(N-1)       % Return the N-1 string.
++string:copies("*",N).
             % Append "*" N times.
++"~n"       % Append a newline.
\$\endgroup\$
1
\$\begingroup\$

Powershell, 24 bytes

1.."$args"|%{$a+="*";$a}
\$\endgroup\$
1
1
\$\begingroup\$

C++ (gcc), 65 bytes

#include<ios>
int f(int n){for(n&&f(n-1);~n;putchar(n--?42:10));}

Including the #include in the byte count.

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ You can shave off 8 bytes by just making it f(n){; int is implied as both parameter and return type. \$\endgroup\$
    – Moonchild
    Jul 13 '20 at 8:37
1
\$\begingroup\$

Add++, 11 bytes

L,R"*"€*BFn

Try it online!

A function that returns the string given an argument \$n\$.

A full program is 17 bytes:

y:?
Ey,x:"*",*i,O

Try it online!

How they work

L,		; Define "anonymous" function
		; It takes one argument, e.g	5
	R	; Range			STACK = [[1 2 3 4 5]]
	"*"	; Push "*"		STACK = [[1 2 3 4 5] "*"]
	€	; For each i:
	 *	;   Repeat "*" i times	STACK = [["*" "**" "***" "****" "*****"]]
	BF	; Flatten		STACK = ["*" "**" "***" "****" "*****"]
	n	; Join by newlines	STACK = ['*\n**\n***\n****\n*****']
		; Return the top value
y:?		; y = input()
Ey,		; for i in range(y):
	x:"*",	;   x = "*"
	*i,	;   x *= i
	O	;   print(x)
\$\endgroup\$
1 2 3 4
5

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.