34
\$\begingroup\$

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!

\$\endgroup\$
17
  • 4
    \$\begingroup\$ Does it need to be a program or can it be a function? \$\endgroup\$ Commented Feb 8, 2017 at 15:04
  • 8
    \$\begingroup\$ 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) \$\endgroup\$ Commented Feb 8, 2017 at 15:10
  • 4
    \$\begingroup\$ @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 \$\endgroup\$ Commented Feb 8, 2017 at 16:04
  • 9
    \$\begingroup\$ 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 (-)". \$\endgroup\$ Commented Feb 8, 2017 at 17:48
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Commented Feb 8, 2017 at 18:25

67 Answers 67

12
\$\begingroup\$

C, 58 bytes

i;f(n){for(i=2*n;~i--;printf(i<n?"-":"|%*c\n",2*n-i,92));} 

--

Thanks to @Steadybox who's comments on this answer helped me shave a few bytes in my above solution

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I managed to reach 68, was pretty proud of myself.. and then I scrolled :( -- Well done! \$\endgroup\$ Commented Feb 8, 2017 at 23:58
  • 1
    \$\begingroup\$ Very nice! Have a +1 \$\endgroup\$ Commented Feb 9, 2017 at 0:20
  • \$\begingroup\$ I have 2*n in there twice and it bothers me, can anyone think of a clever way to shorten it somehow? \$\endgroup\$ Commented Feb 9, 2017 at 22:14
  • 1
    \$\begingroup\$ -1 byte and fixes bug for n=0 \$\endgroup\$ Commented Sep 2, 2020 at 5:34
  • \$\begingroup\$ @att Nice! I knew there'd be a way, wow 3 years later too! \$\endgroup\$ Commented Sep 2, 2020 at 7:03
8
\$\begingroup\$

Javascript (ES6), 97 85 81 75 74 bytes

n=>(g=(n,s)=>n?g(--n,`|${" ".repeat(n)}\\ `+s):s)(n,"")+"-".repeat(n&&n+1) 

Turns out I wasn't using nearly enough recursion

f=n=>(g=(n,s)=>n?g(--n,`|${" ".repeat(n)}\\ `+s):s)(n,"")+"-".repeat(n&&n+1) console.log(f(0)) console.log(f(1)) console.log(f(2)) console.log(f(3)) console.log(f(4))

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

05AB1E, 16 15 16 bytes

Saved a byte thanks to Adnan

FðN×…|ÿ\}Dg'-×»? 

Try it online!

Explanation

F } # for N in range [0 ... input-1] ðN× # push <space> repeated N times …|ÿ\ # to the middle of the string "|\" Dg # get length of last string pushed '-× # repeat "-" that many times » # join strings by newline ? # print without newline 
\$\endgroup\$
8
  • \$\begingroup\$ ð×.svy¦…|ÿ\}¹>'-×», guess my idea of .s wasn't as good as I thought. Nice use of ÿ, haven't seen that before. \$\endgroup\$ Commented Feb 8, 2017 at 15:23
  • \$\begingroup\$ @carusocomputing: I considered .s as well as starting with <Ýð× but ran into trouble with the special case with those methods. \$\endgroup\$ Commented Feb 8, 2017 at 15:26
  • \$\begingroup\$ FðN×…|ÿ\}Dg'-×» for 15 bytes \$\endgroup\$ Commented Feb 8, 2017 at 15:33
  • \$\begingroup\$ @Adnan: Nice catch with Dg! Thanks :) \$\endgroup\$ Commented Feb 8, 2017 at 15:37
  • \$\begingroup\$ .s also resulted in nested arrays and flattening which required more bytes. \$\endgroup\$ Commented Feb 8, 2017 at 15:46
5
\$\begingroup\$

V, 18 17 16 bytes

1 byte saved thanks to @nmjcman101 for using another way of outputting nothing if the input is 0

é\é|ÀñÙá ñÒ-xÀ«D 

Try it online!

Hexdump:

00000000: e95c e97c c0f1 d9e1 20f1 d22d 78c0 ab44 .\.|.... ..-x..D 

Explanation (outdated)

We first have a loop to check if the argument is 0. If so, the code below executes (|\ is written). Otherwise, nothing is written and the buffer is empty.

Àñ ñ " Argument times do: é\é| " Write |\ h " Exit loop by creating a breaking error 

Now that we got the top of the triangle, we need to create its body.

Àñ ñ " Argument times do: Ù " Duplicate line, the cursor comes down à<SPACE> " Append a space 

Now we got one extra line at the bottom of the buffer. This has to be replaced with -s.

Ó- " Replace every character with a - x " Delete the extra '-' 

This answer would be shorter if we could whatever we want for input 0

V, 14 13 bytes

é\é|ÀñÙá ñÒ-x 

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I should not have tried that hard for a byte Try it online! \$\endgroup\$ Commented Feb 9, 2017 at 21:18
  • \$\begingroup\$ @nmjcman101 Ah, « of course. Clever! :) \$\endgroup\$ Commented Feb 10, 2017 at 17:15
4
\$\begingroup\$

Jelly, 14 bytes

’⁶x⁾|\jṄµ€Ṫ”-ṁ 

Try it online!

How it works.

’⁶x⁾|\jṄµ€Ṫ”-ṁ Main link. Argument: n µ Combine the links to the left into a chain. € Map the chain over [1, ..., n]; for each k: ’ Decrement; yield k-1. ⁶x Repeat the space character k-1 times, yielding a string. ⁾\j Join the character array ['|', '\'], separating by those spaces. Ṅ Print the result, followed by a linefeed. Ṫ Tail; extract the last line. This will yield 0 if the array is empty. ⁾-ṁ Mold the character '-' like that line (or 0), yielding a string of an equal amount of hyphen-minus characters. 
\$\endgroup\$
0
4
\$\begingroup\$

C#, 93 bytes

n=>{var s=n>0?new string('-',n+1):"";while(n-->0)s="|"+new string(' ',n)+"\\\n"+s;return s;}; 

Anonymous function which returns the ASCII triangle as a string.

Full program with ungolfed, commented function and test cases:

using System; class ASCIITriangles { static void Main() { Func<int, string> f = n => { // creates the triangle's bottom, made of dashes // or an empty string if n == 0 var s = n > 0 ? new string('-', n + 1) : ""; // a bottom to top process while ( n-- > 0) // that creates each precedent line s = "|" + new string(' ', n) + "\\\n" + s; // and returns the resulting ASCII art return s; }; // test cases: Console.WriteLine(f(4)); Console.WriteLine(f(0)); Console.WriteLine(f(1)); } } 
\$\endgroup\$
0
4
\$\begingroup\$

bash + printf, 68 bytes

for((;i<$1;)) { a=$a- printf "|%$[i++]s\\\\\n" } [ $a ] && echo $a- 

Use "bash program_name number" to run. Sample run:

bash-4.1$ bash triangle 0 bash-4.1$ bash triangle 1 |\ -- bash-4.1$ bash triangle 2 |\ | \ --- bash-4.1$ bash triangle 3 |\ | \ | \ ---- 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Very nice. Shaved 3 bytes \$\endgroup\$ Commented Nov 10, 2020 at 19:20
3
\$\begingroup\$

Python 2, 69 bytes

lambda x:'\n'.join(['|'+' '*n+'\\'for n in range(x)]+['-'*-~x*(x>0)]) 

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ If you're printing it, you can save a few bytes by changing to python3, removing "".join and replacing it with the * operator and the sep argument in the sleep function, so lambda x:print(*['|'+' '*n+'\\'for n in range(x)]+['-'*-~x*(x>0)],sep="\n") \$\endgroup\$ Commented Feb 9, 2017 at 6:24
3
\$\begingroup\$

CJam, 24 22 21 bytes

Saved 1 byte thanks to Martin Ender

ri_{S*'|\'\N}%\_g+'-* 

Try it online!

Explanation

ri e# Take an integer from input _ e# Duplicate it { e# Map the following to the range from 0 to input-1 S* e# Put that many spaces '| e# Put a pipe \ e# Swap the spaces and the pipe '\ e# Put a backslash N e# Put a newline }% e# (end of map block) \ e# Swap the top two stack elements (bring input to the top) _g+ e# Add the input's signum to itself. Effectively this increments any e# non-zero number and leaves zero as zero. '-* e# Put that many dashes 
\$\endgroup\$
0
3
\$\begingroup\$

PowerShell, 51 67 bytes

param($n)if($n){1..$n|%{"|"+" "*--$_+"\"};write-host -n ('-'*++$n)} 

Try it online!

(Byte increase to account for no trailing newline)

Takes input $n and verifies it is non-zero. Then loops to construct the triangle, and finishes with a line of -. Implicit Write-Output happens at program completion.

\$\endgroup\$
2
  • \$\begingroup\$ The program prints a trailing newline but I asked output to be exactly as specified, sorry! \$\endgroup\$ Commented Feb 8, 2017 at 15:57
  • 1
    \$\begingroup\$ @Okx Changed at a cost of 16 bytes. \$\endgroup\$ Commented Feb 8, 2017 at 16:02
2
\$\begingroup\$

SmileBASIC, 51 bytes

INPUT N FOR I=0TO N-1?"|";" "*I;"\ NEXT?"-"*(N+!!N) 
\$\endgroup\$
2
\$\begingroup\$

Retina, 39 bytes

.* $* *\`(?<=(.*)). |$.1$* \¶ 1 - -$ -- 

Try it online

Convert decimal input to unary. Replace each 1 with |<N-1 spaces>\¶, print, and undo replace. Replace each 1 with a hyphen, and the last hyphen with 2 hyphens. Tadaa!

\$\endgroup\$
2
\$\begingroup\$

Common Lisp, 89 86 bytes

Creates an anonymous function that takes the n input and prints the triangle to *standard-output* (stdout, by default).

Golfed

(lambda(n)(when(< 0 n)(dotimes(i n)(format t"|~v@t\\~%"i))(format t"~v,,,'-<~>"(1+ n)))) 

Ungolfed

(lambda (n) (when (< 0 n) (dotimes (i n) (format t "|~v@t\\~%" i)) (format t "~v,,,'-<~>" (1+ n)))) 

I'm sure I could make this shorter somehow.

\$\endgroup\$
2
\$\begingroup\$

C 101 93 75 bytes

f(n){i;for(i=0;i++<n;)printf("|%*c\n",i,92);for(;n--+1;)prin‌​tf("-");} 

Ungolfed version

void f(int n) { int i; for(i=0;i++<n;) printf("|%*c\n",i,92); for(;n--+1;) printf("-"); } 

@Steadybox Thanks for pointing out, makes a lot of sense.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ You can shave off a few bytes by replacing character constants with their ASCII value and moving the first i++ in the loop body. And why is printf("%c",'_'); so verbose? \$\endgroup\$ Commented Feb 8, 2017 at 17:34
  • \$\begingroup\$ @Jens stimmt, Danke sehr :) Updated \$\endgroup\$ Commented Feb 8, 2017 at 17:43
  • \$\begingroup\$ This can be cut down to 74 bytes: i;f(n){for(i=0;i++<n;)printf("%c%*c\n",124,i,92);for(;n--+1;)printf("-");} \$\endgroup\$ Commented Feb 8, 2017 at 18:14
  • \$\begingroup\$ To 69 bytes, actually: i;f(n){for(i=0;i++<n;)printf("|%*c\n",i,92);for(;n--+1;)printf("-");} \$\endgroup\$ Commented Feb 8, 2017 at 18:28
  • \$\begingroup\$ @Steadybox 68: n--+1 can be shortened to ~n-- \$\endgroup\$ Commented Feb 8, 2017 at 19:41
2
\$\begingroup\$

Python 3, 60 bytes

f=lambda n,k=0:k<n and'|'+' '*k+'\\\n'+f(n,k+1)or'-'[:n]*-~n 

Try it online!

Two more solutions with the same byte count.

f=lambda n,k=0:n and'|'+' '*k+'\\\n'+f(n-1,k+1)or-~k*'-'[:k] f=lambda n,s='|':-~n*'-'[:n]if s[n:]else s+'\\\n'+f(n,s+' ') 
\$\endgroup\$
2
\$\begingroup\$

dc, 98 bytes

256?dse1+d[q]st1=t^124*23562+dsaP2sk[[lkd256r^32*la+dsaPd1+skle>y]srle1<r]dsyx[45Ple1-dse0!>q]dsqx 

Try it online!

Explanation

This takes due advantage of dc's P command, which utilizes conversion to base 256 on most systems. Therefore, for any input n, the program first raises 256 to the n + 1th power, multiplies the result by 124 (ASCII character |), and then adds 256*92+10=23562 to the product (where 92 is equivalent to the character \ and 10 is the decimal value of the new-line (\n)). This results in a decimal number that when converted to base 256 with P results in the output |\\n where \n is the literal new-line character. A duplicate of this decimal number is also stored on top of register a.

Then, a "macro-loop" is invoked, as long as n > 1, in which a counter is incremented until n, beginning from 2, and, as the 3rd through nth base 256 digits are unset, 256 is raised to each of those increments, a result which is then multiplied by 32 (the ASCII single space character). Then the value on top of register a is incremented by the resulting product, thus, on each iteration, setting each one of the unset base 256 digits in the between the | and the \ characters to a single space.

Finally, after all n-1 lines have been output, another "macro-loop" is invoked in which all the n+1 dashes are output through the feeding of 45 to P on each iteration.

Note: The [q]st1=t segment makes sure that nothing is output for the input 0 by checking if the incremented input is equal to one, and if it is, simply executes the macro [q] which exits the program.

\$\endgroup\$
2
\$\begingroup\$

Charcoal, 15 bytes

Nβ¿β«↓β→⁺¹β↖↖β» 

Try it online!

Breakdown

Nβ¿β«↓β→⁺¹β↖↖β» Nβ assign input to variable β ¿β« » if β != 0: ↓β draw vertical line β bars long →⁺¹β draw horizontal line β+1 dashes long ↖ move cursor up one line and left one character ↖β draw diagonal line β slashes long 
\$\endgroup\$
1
  • \$\begingroup\$ Very late comment, but the closing » can be omitted. \$\endgroup\$ Commented Nov 9, 2017 at 7:24
2
\$\begingroup\$

Japt, 20 bytes

Saved 2 bytes thanks to @ETHproductions

o@'|+SpX +'\Ãp-pUÄ)· 

Try it online!

Explanation

o@'|+SpX +'\Ãp-pUÄ)· o // Creates a range from 0 to input @ // Iterate through the array '|+ // "|" + SpX + // S (" ") repeated X (index) times + '\Ã // "\" } p-pU // "-" repeated U (input) +1 times Ä)· // Join with newlines 
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice one! You can save a byte by pushing the last row before joining: o@'|+SpX +'\Ãp'-pUÄ)· and due to a bug (really an unintentional side effect of auto-functions), you can then remove the ' in '-. \$\endgroup\$ Commented Mar 4, 2017 at 17:07
  • \$\begingroup\$ Actually, it's like that with all lowercase letters, not just p. That's so you can do e.g. m*2 to double each element, or mp2 to square each \$\endgroup\$ Commented Mar 4, 2017 at 18:44
2
\$\begingroup\$

J, 20 bytes

-13 bytes thanks to bob

*#' \|-'{~3,~2,.=@i. 

Try it online!

original: 33 bytes

(#&'| \'@(1,1,~])"0 i.),('-'#~>:) 

ungolfed

(#&'| \' @ (1,1,~])"0 i.) , ('-'#~>:) 

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ 25 bytes with *,&'-' '|',.'\'{."0~_1-i. \$\endgroup\$ Commented Jul 21, 2017 at 9:52
  • \$\begingroup\$ 22 bytes with *,&'-' '|',.' \'{~=@i. \$\endgroup\$ Commented Jul 23, 2017 at 9:09
  • \$\begingroup\$ @bob That was very clever to use identity matrix \$\endgroup\$ Commented Jul 24, 2017 at 7:25
  • \$\begingroup\$ @bob thanks for the suggestion. i've updated the post \$\endgroup\$ Commented Nov 9, 2017 at 3:14
2
\$\begingroup\$

Commodore BASIC (C64/128, TheC64 & Mini, VIC-20, PET, C16/+4) - 46 BASIC Bytes

0inputn:ifnthenfori=1ton:?"{shift+B}{left}"spc(i)"{shift+M}":next:fori=.ton:print"-";:next 

There is a sanity check for zero, but any other positive integer will work.

Note, a C64 has 25 rows and 40 columns text (some PETs and the C128 in VDC mode has 80 columns, the VIC-20 is 22 columns by 23 rows) so the output will be skewed if you exceed the screen limit in either direction.

I've added a screenshot so that you may see the PETSCII characters that I can't make happen in this listing.

Commodore C64 Triangle challenge

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

Pyke, 18 17 bytes

I Fd*\|R\\s)Qh\-* 

Try it here!

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

Python2, 73 bytes

n=input() w=0 exec'print"|"+" "*w+"\\\\"+("\\n"+"-"*-~n)*(w>n-2);w+=1;'*n 

A full program. I also tried string interpolation for the last line, but it turned out be a couple bytes longer :/

exec'print"|%s\\\\%s"%(" "*w,("\\n"+"-"*-~n)*(w>n-2));w+=1;'*n 

Another solution at 73 bytes:

n=j=input() exec'print"|"+" "*(n-j)+"\\\\"+("\\n"+"-"*-~n)*(j<2);j-=1;'*n 

Test cases

0: 1: |\ -- 2: |\ | \ --- 3: |\ | \ | \ ---- 6: |\ | \ | \ | \ | \ | \ ------- 
\$\endgroup\$
2
  • \$\begingroup\$ I apologise for my previous comment, functions are now allowed. \$\endgroup\$ Commented Feb 8, 2017 at 16:24
  • \$\begingroup\$ @Okx No problem. This stands as a full program. I don't think I'll look into the fashion of a function solution :) \$\endgroup\$ Commented Feb 8, 2017 at 16:25
1
\$\begingroup\$

MATL, 19 bytes

?'\|- '2GXyYc!3Yc!) 

Try it online!

? % Implicit input. If non-zero '\|- ' % Push this string 2 % Push 2 G % Push input Xy % Identity matrix of that size Yc % Prepend a column of 2's to that matrix ! % Transpose 3 % Push 3 Yc % Postpend a column of 3's to the matrix ! % Transpose ) % Index into string % Implicit end. Implicit display 
\$\endgroup\$
1
\$\begingroup\$

QBIC, 41 bytes

:~a>0|[a|?@|`+space$(b-1)+@\`][a+1|Z=Z+@- 

Explanation

:~a>0| Gets a, and checks if a > 0 If it isn't the program quits without printing anything [a| For b=1; b <= a; b++ ?@|`+ Print "|" space$ and a number of spaces (b-1) euqal to our current 1-based line - 1 +@\` and a "\" ] NEXT [a+1| FOR c=1; c <= a+1; c++ Z=Z+@- Add a dash to Z$ Z$ gets printed implicitly at the end of the program, if it holds anything The last string literal, IF and second FOR loop are closed implicitly. 
\$\endgroup\$
1
\$\begingroup\$

R, 101 bytes

for(i in 1:(n=scan())){stopifnot(n>0);cat("|",rep(" ",i-1),"\\\n",sep="")};cat("-",rep("-",n),sep="") 

This code complies with the n=0 test-case if you only consider STDOUT !
Indeed, the stopifnot(n>0) part stops the script execution, displays nothing to STDOUT but writes Error: n > 0 is not TRUE to SDTERR.

Ungolfed :

for(i in 1:(n=scan())) { stopifnot(n>0) cat("|", rep(" ", i-1), "\\\n", sep = "") } cat("-", rep("-", n), sep = "") 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Might want to fix the spelling of ungolfed \$\endgroup\$ Commented Feb 8, 2017 at 17:21
1
\$\begingroup\$

Python 2, 62 bytes

n=input();s='\\' exec"print'|'+s;s=' '+s;"*n if n:print'-'*-~n 

Try it online!

Prints line by line, each time adding another space before the backslash. If a function that doesn't print would be allowed, that would likely be shorter.

\$\endgroup\$
1
  • \$\begingroup\$ Apparently, functions do not have to print. \$\endgroup\$ Commented Feb 9, 2017 at 12:02
1
\$\begingroup\$

JavaScript (ES6), 71 bytes

f= n=>console.log(' '.repeat(n).replace(/./g,'|$`\\\n')+'-'.repeat(n+!!n))
<form onsubmit=f(+i.value);return!true><input id=i type=number><input type=submit value=Go!>

Outputs to the console. Save 6 bytes if printing to the SpiderMonkey JavaScript shell is acceptable. Save 13 bytes if returning the output is acceptable.

\$\endgroup\$
1
  • \$\begingroup\$ That regex is ingenious. I first tried something along those lines. I din't know about the $` pattern, but don't know if I still would've thought of it. Nice. \$\endgroup\$ Commented Feb 8, 2017 at 21:12
1
\$\begingroup\$

Befunge-98, 68 bytes

&:!#@_000pv< :kg00 ',|'<|`g00:p00+1g00,a,\'$,kg00 00:k+1g00-'<@,k+1g 
\$\endgroup\$
3
  • \$\begingroup\$ This looks like a very nice first answer, but when I try it online, I get the wrong results. Any idea what's wrong there? \$\endgroup\$ Commented Feb 8, 2017 at 20:22
  • \$\begingroup\$ @DJMcMayhem I checked it, the TIO gives k instruction one more execution (executes pop()+1 times). Bug in their implementation. \$\endgroup\$ Commented Feb 8, 2017 at 20:40
  • \$\begingroup\$ @UrielEli which interpreter are you using? According to a github issue there is one weird (cfunge) that does this,like you, but all the others, including TIO work as intended (see here github.com/catseye/FBBI/issues/1#issuecomment-272643932) \$\endgroup\$ Commented Feb 8, 2017 at 21:10
1
\$\begingroup\$

Python 2, 67 bytes

Another function in Python 2, using rjust.

lambda n:('|'.join(map('\\\n'.rjust,range(n+2)))+'-'*-~n)[4:]*(n>0) 

Try it online!

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

Perl, 63 bytes

$n=shift;print'|',$"x--$_,"\\\n"for 1..$n;print'-'x++$n,$/if$n 

Ungolfed:

$ perl -MO=Deparse triangle.pl $n = shift @ARGV; print '|', $" x --$_, "\\\n" foreach (1 .. $n); print '-' x ++$n, $/ if $n; 

$" is the list separator, which defaults to " ". $/ is the output record separator, which defaults to "\n". $_ is the implicit loop variable.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ probably could save some by reading the input off of stdin?$n=<>? \$\endgroup\$ Commented Feb 22, 2017 at 19:17

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.