ASCII Triangles

Your task is to write a program or a function that prints an ASCII triangle. They look like this:

|\
| \
|  \
----


Your program will take a single numeric input n, with the constraints 0 <= n <= 1000. The above triangle had a value of n=3.

The ASCII triangle will have n backslashes (\) and vertical bars (|), n+1 lines and dashes (-), and each line will have an amount of spaces equal to the line number (0-based, ie first line is line 0) besides the ultimate line.

Examples:

Input:

4


Output:

|\
| \
|  \
|   \
-----


Input:

0


Output:

In this test case, the output must be empty. No whitespace.

Input:

1


Output:

|\
--


Input & output must be exactly how I specified.

This is , so aim for the shortest code possible!

• Does it need to be a program or can it be a function? Commented Feb 8, 2017 at 15:04
• I think it would be better if case 0 can have any unexpected output since it is an edge case (especially since you requested that the number of dashes must be one more than the input number) Commented Feb 8, 2017 at 15:10
• @Okx There are frequently questions where the asker says program but really meant program or function. You might want to clarify that you are asking for a FULL program Commented Feb 8, 2017 at 16:04
• I would definitely go for both program and function. That's the default rule if nothing else is specified. I would also remove the 0-edge case since it's a direct violation of "n+1 lines and dashes (-)". Commented Feb 8, 2017 at 17:48
• The challenge would be too simple without the size=0 exception. Part of the challenge is figuring out a way to account for this with the least amount of extra code. Commented Feb 8, 2017 at 18:25

(($1))&&(echo '|\';(($1-1))&&$0$[$1-1]|sed 's/|/| /;s/-/--/'||echo --)  Test program: for n in 0 1 2 3 4 5; do echo$n; ./triangle $n; echo; done  Test output: 0 1 |\ -- 2 |\ | \ --- 3 |\ | \ | \ ---- 4 |\ | \ | \ | \ ----- 5 |\ | \ | \ | \ | \ ------  Haskell, 82 65 bytes g 0="" g n=((take n$iterate(' ':)"\\\n")>>=('|':))++([0..n]>>"-")


Try it online! Usage:

Prelude> g 4
"|\\\n| \\\n|  \\\n|   \\\n-----"


Or more nicely:

Prelude> putStr $g 4 |\ | \ | \ | \ -----  Pyth, 23 18 bytes VQ++\|*dN\\)IQ*\-h  Test suite available online. Thanks to Ven for golfing off 5 bytes. Explanation VQ++\|*dN\\)IQ*\-h Q Q Q [Q is implicitly appended, initializes to eval(input)] d [d initializes to ' ' (space)] VQ ) For N in range(0, eval(input)): *dN Repeat space N times +\| Prepend | + \\ Append \ Implicitly print on new line IQ If (input): [0 is falsy, all other valid inputs are truthy] hQ Increment input by 1 *\- Repeat - that many times Implicitly print on new line  brainf**k, 256 bytes [-]>[-]+[[-]>[-],[+[-----------[>[-]++++++[<------>-]<--<<[->>++++++++++<<]>>[-<<+>>]<+>]]]<]<>++++++++++[>+>+++>++++>+++++++++>++++++++++++<<<<<-]>>++>+++++>++>++++<<<<<<[>[-]+>>>>>.>[>+<<<<<.>>>>-]>[-<+>]<<<.>>+<<<<<.<<-]>>>>>>>[<<<.>>>-]<<<<<<[>>>.<<<-]  Try it online! How it works # Read input and convert to number (https://esolangs.org/wiki/Brainfuck_algorithms#Input_a_decimal_number) [-]>[-]+[[-]>[-],[+[-----------[>[-]++++++[<------>-]<--<<[->>++++++++++<<]>>[-<<+>>]<+>]]]<]< # We need the characters {LF} (10); {space} (32); {minus} (45); $$92) | (120) P1 > ++++++++++ [ p0 < P1 > P2 > + P3 > +++ P4 > ++++ P5 > +++++++++ P6 > ++++++++++++ P5 < P4 < P3 < P2 < P1 < - ] P0 < # Contains n P1 > # is zero P2 > # is {LF} P3 > ++ # is {space} P4 > +++++ # is {minus} P5 > ++ # is \ P6 > ++++ # is | p5 < p4 < p3 < p2 < p1 < p0 < [ # Loop through n P1 >[-]+ # p1 will be 1 if input was not 0; used to output the additional {minus} p2 > p3 > p4 > p5 > p6 > . ## output p7 spaces; copy p7 to p8 p7 > [ p8 > + p7 < p6 < p5 < p4 < p3 < . # output {space} p4 > p5 > p6 > p7 > - ] ## copy p8 back to p7 p8 > [ - p7 < + p8 > ] p7 < p6 < p5 < . # output \ p6 > p7 > + # increase number of spaces p6 < p5 < p4 < p3 < p2 < . # output {LF} p1 < p0 < - ] p1 > p2 > p3 > p4 > p5 > p6 > ## output p7 minuses p7 > [ p6 < p5 < p4 < . p5 > p6 > p7 > - ] p6 < p5 < p4 < p3 < p2 < ## output additional minus p1 < [ p2 > p3 > p4 > . p3 < p2 < p1 < - ]  This is my first contribution and I'm not sure whether it is allowed to re-use code from others. My code above uses the code published in the Wiki to read the input characters and convert them into a number. Hope that's okay. • Welcome to the site! It is ok to use code that is freely available here. However I will say that we do usually allow brainfuck to take input by character code. It does depend on the challenge a bit, because character codes are usually limited to 255, but with the right interpreter or compiler this bound is often optional. Commented Dec 14, 2019 at 1:13 Python 3, 72 71 bytes x=int(input()) for i in range(x):print('|'+' '*i+'\\') print('-'*(x+1))  Try it online! Python 2, 62 bytes x=input() for i in range(x):print'|'+' '*i+'\\' print'-'*(x+1)  Try it online! • Welcome to Code Golf! You can remove three of your spaces to save 3 bytes. Commented Feb 12, 2020 at 17:54 • @Stephen, thanks! One question since im new, how do you cross out the previous score in the title? – Dion Commented Feb 14, 2020 at 5:51 • You can use a <s> tag, so like <s>72</s>. Commented Feb 14, 2020 at 5:58 • You can actually remove all the spaces so that the for loop is on one line. Additionally, the last line of dashes should be one longer – Jo King Commented Feb 19, 2020 at 22:14 C, 115 112 bytes i,n,w;f(){if(n){for(i=n;i--;){w=n-i;printf("|");for(;0<--w;)printf(" ");puts("\\");}for(i=n;~i--;)printf("-");}}  Try it online! x86-32 machine code, 87 bytes bd00 8089 ecbb 0400 83fb 0074 fe89 d989 d829 c850 b40e b07c cd10 5851 89c1 4183 f901 7502 7408 50b4 0eb0 20cd 1058 90e2 ee50 b40e b05c cd10 5850 b40e b00a cd10 b00d cd10 5859 e2c7 89d9 4150 b40e b02d cd10 58e2 f6eb fe  To boot, pad it to 510 bytes with zeros and add 55aa at the end! This means "add times 510 - (-) db 0 and db 0xaa55 to the ungolfed assembly code". Ungolfed (compilable, compile using nasm -fbin -o triangles triangles.asm): [org 0x7c00] [bits 16] mov bp, 8000h ; set up stack mov sp, bp mov bx, 4 ; N ; cx = i, bx = n, ax = w cmp bx, 0 ; if n == 0, don't print anything je mov cx, bx ; i = n l1: ; first for mov ax, bx sub ax, cx ; w = n - i push ax mov ah, 0eh mov al, '|' int 10h ; print | pop ax push cx mov cx, ax inc cx l2: ; second for (prints whitespaces) cmp cx, 1 ; if (i != 1) print " "; - there was a bug with first \ printing far right from the triangle jne l2_1 je l2_2 l2_1: push ax mov ah, 0eh mov al, ' ' int 10h pop ax l2_2: nop loop l2 ; while i < 0 l2(); i--; push ax mov ah, 0eh mov al, '\' int 10h ; print backslash pop ax push ax mov ah, 0eh mov al, 0ah int 10h mov al, 0dh int 10h ; print newline pop ax pop cx loop l1 ; while i < 0 l1(); i--; mov cx, bx ; i = n inc cx ; i++ l3: ; third for (prints dashes) push ax mov ah, 0eh mov al, '-' int 10h pop ax loop l3 ; while i < 0 l3(); i--; jmp ; hang forever $$$$  Pip-n, 21 bytes IaO['|.sX,a.'\'-Xa+1]  Try it online! Explanation IaO['|.sX,a.'\'-Xa+1] s is space; a is 1st command-line arg (implicit) Ia If a is nonzero: O Output this expression without a trailing newline: [ ] A list containing these two items: sX,a A list of increasing runs of spaces '|. with a pipe character concatenated to the front of each run .'\ and a slash concatenated to the back '-Xa+1 A string of a+1 hyphens  For example: with an input of 3, the list will be [["|\"; "| \"; "| \"]; "----"]. The -n flag separates all items of a list with newlines when it is printed, so we get |\ | \ | \ ----  The if statement means the program does nothing if the input a is 0, as required. APL (Dyalog Unicode), 41 33 bytes {×⍵:↑({'\',⍨⍵↑'|'}¨⍳⍵),⊂'-'⍴⍨⍵+1}  Try it online! -7 bytes from Adám. -1 byte using signum function. Explanation {×⍵:↑({'\',⍨⍵↑'|'}¨⍳⍵),⊂'-'⍴⍨⍵+1} ⍝ ⍵=n ×⍵: ⍝ If sign(n) '-'⍴⍨⍵+1 ⍝ Repeat '-' n+1 times ⊂ ⍝ Enclose it to a single string , ⍝ Join with }¨⍳⍵ ⍝ for each x in range 1..n ⍵↑'|' ⍝ Inner fn: take x characters from '|' appending spaces '\',⍨ ⍝ Reverse join with '\'  Try it online! • 34 – Adám Commented Nov 10, 2020 at 17:52 • @Adám leaving it unmixed gives an interesting pattern. Commented Nov 11, 2020 at 4:43 VyxalṀosr, 12 bytes ⟑I‛|\j…;tƛ\-  Try it Online! Flags FTW ⟑I‛|\j…;tƛ\- ⟑ # Over each in [0, n) (not [1, n] thanks to Ṁ flag) I # Push n spaces ‛|\j # Join ['|', '\'] by that (r flag makes the arguments reversed) … # Print it with a trailing newline (without popping) ; # Close loop t # Get the last element ƛ\- # Replace each with a hyphen # o flag - force implicit output # s flag - join this list of hyphens to a single string  Javascript 101(Full Program), 94(Function Output), 79(Return) bytes Full Program Will not run in Chrome (as process doesn't exist apparently) Will not run in TIO (as prompt apparently isn't allowed) x=prompt();s='';for(i=0;i<x;i++)s+='|'+' '.repeat(i)+\\ ;process.stdout.write(s+'-'.repeat(x&&x+1))  Function with EXACT print x=>{s='';for(i=0;i<x;)s+='|'+' '.repeat(i++)+\\ ;process.stdout.write(s+'-'.repeat(x&&x+1))}  Try it Online Function with return string x=>{s='';for(i=0;i<x;)s+='|'+' '.repeat(i++)+\\ ;return s+'-'.repeat(x&&x+1)}  Try it Online Repeating characters in Javascript is dumb and so is suppressing newlines on output Python 2, 82 bytes def f(i,c=0): if c<i:print'|'+' '*c+'\\';f(i,c+1) print'-'*((c+1,c)[c<1]);exit()  Try it online! Longer that the other Python answers but a recursive function just to be different. It feels wasteful using two print statements but I can't find a shorter way round it. Also the exit() wastes 7 to stop it printing decreasing number of - under the triangle. • You can do -~c*(c>0) on the last line to save 3 bytes :) Commented Feb 9, 2017 at 17:58 • Or better yet: c and-~c. Commented Feb 10, 2017 at 17:42 Javascript (ES6), 84 bytes Creates an anonymous function that presents the result on an alert box. No output is present if 0. i=>{for(X=i,a='';i--;)a='|'+(' '.repeat(i))+'\\\n'+a;X&&alert(a+('-'.repeat(++X)))}  If printing is really required (137 bytes): i=>for(X=i,d=document.body;i--;)d.innerHTML='|'+('&nbsp;'.repeat(i))+'\\<br>'+d.innerHTML;X&&window.print(d.innerHTML+=('-'.repeat(++X)))  Changes the HTML code and prints the page into a paper sheet. The page stays white if 0. • @LliwTelracs Should work now. If it is required to show the alert when it is 0, I can do it without increasing the size again. Commented Feb 8, 2017 at 19:07 Clojure, 104 bytes (fn[h](let[r #(apply str(repeat % %2))](doseq[n(range h)](println(str\|(r n\ )\$$))(print(r(inc h)\-))))  At least I should have lots of room to golf from here! Loops over the range from 0 to h-1, printing a \|, then h-many spaces, then a \\. Finally, at the end, it prints h+1 many dashes. (defn triangle [hypot-n] (let [r #(apply str (repeat % %2))] ; Create a shortcut string repeat function, since I need it twice. (doseq [line-n (range hypot-n)] ; Loop over the range 0 to hypot... (println (str \| (r line-n \ ) \\))) ; Printing a bar, then line-n many spaces, then a slash (print (r (inc hypot-n) \-)))) ; Then print the trailing dashes  Batch, 110 bytes @set s= @for /l %%i in (1,1,%1)do @call:c @if %1 gtr 0 echo -%s: =-% @exit/b :c @echo ^|%s%\ @set s= %s%  Special-casing 0 is no hardship as %s: =-% would fail anyway. JavaScript, 66 bytes f=(x,i=0)=>i<x?|${" ".repeat(i)}\\\n+f(x,i+1):"-".repeat(x&&i+1)


Mathematica, 57 bytes

Array[{"|"," "~Table~#,"\\
"}&,#,0]<>Table["-",#+Sign@#]&


Unnamed function taking a nonnegative integer as input and returning a string-with-newlines. It deals with the special case of input 0 by noting that the number of dashes is equal to the input plus the sign of the input.

Ruby, 48 bytes

->n{puts ?-*(n.times{|x|puts ?|+' '*x+?\\}+(n<=>0))}


Jelly, 19 bytes

Ḷ×⁶j@€⁾|\;‘×”-$$YxṠ  Try it online! Explanation: Ḷ×⁶j@€⁾|\;‘×”-$$YxṠ Link 0. Arguments: z.
Ḷ                   Range from 0 to z - 1. [arg-z]
⁶                 Space (' ').
×                  Product of x and y. [multi-char-string-warning]
⁾|\           Two char string ("|\").
j                Join x on y.
@               Reverse arguments.
€              Convert this link to a map on the left argument.
‘         Increment z. [arg-z]
”-      Character ('-').
×        Product of x and y. [multi-char-string-warning]
$Merge last two links to a monadic link.$    Merge last two links to a monadic link.
;          Concatenate x and y.
Y   Join z on newlines ('\n').
Ṡ Sign of z. [arg-z]
x  Repeat x y times.

PHP, 75 bytes

(70 bytes if I used extended ascii)

for($p=str_pad;+$i<$argv[1];)echo$p("|",++$i),"\\ ";echo$p("",$i+!!$i,"-");


takes input from command line argument. Run with -nr.

Swift 3 96 bytes

var a=5,b="";for c in 0..<a{var d="|";for _ in 0..<c{d+=" "};print(d+"\\");b+="-"};print(b+"-")

• Can you do var a=5,b=""; in Swift? Commented Feb 14, 2017 at 12:17
• Yes its possible Commented Feb 14, 2017 at 12:18
• Also can't you do print(b+"-") instead of b+="-";print(b)? Commented Feb 14, 2017 at 12:20
• I guess now its perfect Commented Feb 14, 2017 at 12:27
• Also var a=5,b="",d;for c in 0..<a{d="|" instead of the beginning of the loop if it works Commented Feb 14, 2017 at 12:29

Python 3, 75 bytes

def x(n):
if n:
for i in range(n):print('|'+' '*i+'\\')
print('-'*-~n)


Try it online!

Here's my Python 3 answer, and it's pretty long. I wonder how I can shorten it...

Thanks to Eric The Outgolfer for helping in the comments...

8th, 94 89 bytes

Code

: f 0; dup ( "|" . ( " " . ) swap times "\\" . cr ) 0 rot n:1- loop n:1+ "-" swap s:* . ;


Explanation

The word f requires an integer input

: f \ n --
0;                      \ Exit if input equals to 0
dup                     \ Duplicate input on the stack
( "|" .                 \ Print a piece of the vertical side
( " " . ) swap times    \ Print space between sides
"\\" . cr )             \ Print a piece of the slanted side
0 rot n:1- loop         \ Repeat the above operation for the size required
n:1+ "-" swap s:* .     \ Print the bottom side
;


Usage

ok> 4 f
|\
| \
|  \
|   \
-----


Python 3, 61 bytes

n=5
q="".join(map(lambda x:"|%s\\\n"%(x*" "),range(n)))+"-"*n


Try it online!

Perl 5, 50 +2 (-ap) = 52 bytes

$_&&='|\\';say,s/\\/$&/ while\$F[0]--;s/./-/g;chop


Try it online!

Acc!!, 179 bytes

N
Count d while _%60-10 {
(_/60*10+_%60-48)*60+N
}
_/60
Count r while _-r {
Write 124
Count s while r-s {
Write 32
}
Write 92
Write 10
}
Count h while _+3*_/(3*_-1)-h {
Write 45
}


Try it online!

Explanation

Load a number into the accumulator, print that many rows of | ... \, and print that many (plus 1) hyphens. Unless the number is 0, in which case print 0 hyphens. No trailing newline in any case.

Most of the code is quite straightforward (handy loop variable mnemonics: digit, row, space, and hyphen). The two interesting parts are inputting a multi-digit number and handling the 0 case.

Inputting a number

N
Count d while _%60-10 {
(_/60*10+_%60-48)*60+N
}
_/60


We divide the accumulator into two sections: _%60 stores the ASCII code of the character we just read, and _/60 stores the number we're constructing. We loop until _%60 is 10--that is, when we encounter a newline. Inside the loop, _%60 is the ASCII code of the new least-significant digit. _%60-48 is the digit itself. _/60 is the previous value of the number, so we multiply that by 10 and add the new digit to get the new value of the number: _/60*10+_%60-48. Multiply that quantity by 60 and add the next input character N, and we're ready to loop. After the loop finishes, we set the accumulator to _/60, the stored number itself.

Handling the 0 case

Count h while _+3*_/(3*_-1)-h {


My original loop condition was _+1-h: loop (accumulator + 1) times. But if the accumulator is 0, we want to loop 0 times, not 1. So instead of adding 1, we add 3*_/(3*_-1). When _ is 0, this quantity is 0. When _ is greater than 0, this quantity is 1 (since 3*_ is less than twice 3*_-1).

Java 8, 109 bytes

n->{String r="|\\\n";int i=0;for(;++i<n;r+=r.format("|%"+i+"s\\%n",""));for(;i-->=0;r+="-");return n<1?"":r;}


Can most likely be golfed some more.

Explanation:

Try it here.

n->{                 // Method with integer parameter and String return-type
String r="|\\\n";  //  Result-string, starting at "|\" + new-line
int i=0;           //  Index-integer, starting at 0
for(;++i<n;        //  Loop (1) from 1 to n (exclusive)
r+=              //   Append to the result-String:
r.format("|   //    A literal "|"
%"+i+"s      //    + i amount of spaces
\\           //    + a literal "\"
%n","")      //    + a new-line
);                 //  End of loop (1)
for(;i-->=0;       //  Loop (2) from n down to 0 (inclusive)
r+="-"           //   Append that many literal "-" to the result-String
);                 //  End of loop (2)
return n<1?        //  If the input was 0:
""               //   Return an empty String
:                 //  Else:
r;               //   Return the result-String
}                    // End of method


VBA Excel, 68 65 bytes

Using Immediate Window and [a1] as input

for x=0to[a1]-1:?"|"string(x,32)"\":next:if x then?string(x+1,45)

• You can drop this down to 65 bytes For i=0To[A1-1]:?"|"String(i,32)"\":Next:If i Then?String(i+1,45) Commented Dec 18, 2017 at 18:22

SNOBOL4 (CSNOBOL4), 98 bytes

	N =INPUT
T	OUTPUT =LT(X,N) '|' DUPL(' ',X) '\'	:F(E)
X =X + 1	:(T)
E	OUTPUT =DUPL('-',X + 1)
END


Try it online!

Japt-R, 14 bytes

°Æ'\i|úXÄÃpUç-


Try it

°Æ'\i|úXÄÃpUç-     :Implicit input of integer U
°                  :Postfix increment U
Æ                 :Map each X in the range [0,U)
'\               :  Literal "\"
i              :  Prepend
|ú            :    "|" right padded with spaces to length
XÄ          :   X+1
Ã         :End map
p        :Push
Uç-     :  "-" repeated U (now incremented) times
:Implicit output, joined with newlines


Underload, 58 39 bytes

:()~(|)~(~!((-):S~^S)~:S( )*(\
)S)~^^!^


Assumes the input is a Church numeral on the stack.

Explanation

          stack (assume input N = 2):
(:*)
:         keep a copy of the input on the bottom
(:*)(:*)
()~       insert the finalization snippet
(:*)()(:*)
(|)~      insert the accumulator
(:*)()(|)(:*)
(...)~^^  run (...) N times:

~!(...)~  set finalization snippet
(:*)((-):S~^S)(|)
:S        output copy of accumulator
(:*)((-):S~^S)(|)           output = |
( )*      append space to accumulator
(:*)((-):S~^S)(| )          output = |
(\;)S     output backslash and newline
(:*)((-):S~^S)(| )          output = |\;

~!(...)~  set finalization snippet
(:*)((-):S~^S)(| )
:S        output copy of accumulator
(:*)((-):S~^S)(| )          output = |\;|
( )*      append space to accumulator
(:*)((-):S~^S)(|  )         output = |\;|
(\;)S     output backslash and newline
(:*)((-):S~^S)(|  )         output = |\;| \;

!         delete accumulator
(:*)((-):S~^S)                  output = |\;| \;
^         execute finalization snippet:
(:*)                            output = |\;| \;

(-)       push hyphen
(:*)(-)                     output = |\;| \;
:S        output hyphen
(:*)(-)                     output = |\;| \;-
~^        repeat N times
(--)                        output = |\;| \;-
S         print
output = |\;| \;---
`