Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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! No specific answer will be accepted, but I will up vote ones I like.

share|improve this question
4  
Does it need to be a program or can it be a function? – LliwTelracs 20 hours ago
5  
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) – Kritixi Lithos 20 hours ago
4  
@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 – LliwTelracs 19 hours ago
6  
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 (-)". – Stewie Griffin 17 hours ago
2  
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. – 12Me21 16 hours ago

30 Answers 30

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
share|improve this answer
    
ð×.svy¦…|ÿ\}¹>'-×», guess my idea of .s wasn't as good as I thought. Nice use of ÿ, haven't seen that before. – carusocomputing 19 hours ago
    
@carusocomputing: I considered .s as well as starting with <Ýð× but ran into trouble with the special case with those methods. – Emigna 19 hours ago
    
FðN×…|ÿ\}Dg'-×» for 15 bytes – Adnan 19 hours ago
    
@Adnan: Nice catch with Dg! Thanks :) – Emigna 19 hours ago
    
.s also resulted in nested arrays and flattening which required more bytes. – carusocomputing 19 hours ago

C, 58

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

share|improve this answer
1  
I managed to reach 68, was pretty proud of myself.. and then I scrolled :( -- Well done! – Quentin 11 hours ago
1  
Very nice! Have a +1 – Steadybox 11 hours ago

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));
    }
}
share|improve this answer
1  
Apparently, the function has to print the string. – TuukkaX 18 hours ago

V, 18 17 bytes

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

Try it online!

Explanation

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!

share|improve this answer

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
share|improve this answer

Python 2, 69 bytes

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

Try it online!

share|improve this answer
1  
Apparently, the function has to print the string :/ – TuukkaX 18 hours ago
    
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") – sagiksp 4 hours ago

C 101 93 bytes

f(n){i;for(i=0;i<n;i++){printf("%c%*c",124,i+1,92);puts("\n");}for(i=0;i<n;i++)printf("_");}

Ungolfed version

void f(int n)
{
  int i;

  for(i=0;i<n;i++)
  {    
     printf("%c%*c",124,i+1,92);
     puts("\n");    
  }
  for(i=0;i<=n;i++)
    printf("-");

}
share|improve this answer
1  
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? – Jens 17 hours ago
    
@Jens stimmt, Danke sehr :) Updated – Abel Tom 17 hours ago
    
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("-");} – Steadybox 17 hours ago
    
To 69 bytes, actually: i;f(n){for(i=0;i++<n;)printf("|%*c\n",i,92);for(;n--+1;)prin‌​tf("-");} – Steadybox 16 hours ago
    
@Steadybox 68: n--+1 can be shortened to ~n-- – Albert Renshaw 15 hours ago

Javascript (ES6), 97 85 81 75 bytes

n=>(g=(n,s)=>n?g(--n,`|${" ".repeat(n)}\\\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)}\\\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))

share|improve this answer
    
So that running the function in a console implicitly outputs the string doesn't count? There are many other solutions already that don't print but rather returns the output. Rather, most current solutions don't – Jan 18 hours ago
    
"Printing" is not even an Ecmascript concept. Printing only exists within the respective implementations, so I would have to specify which debugger to run it in (like ES6 on chrome) which would be silly. That it outputs the string with quotation marks only means that it's outputting a string. If that's a requirement I guess I'll remove the solution. – Jan 18 hours ago
    
@LliwTelracs It's currently shorter than your pure function solution, so for that purpose it's not that bad ;) – Jan 15 hours ago

Pyke, 18 17 bytes

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

Try it here!

share|improve this answer

SmileBASIC, 51 bytes

INPUT N
FOR I=0TO N-1?"|";" "*I;"\
NEXT?"-"*(N+!!N)
share|improve this answer

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.

share|improve this answer
    
The program prints a trailing newline but I asked output to be exactly as specified, sorry! – Okx 19 hours ago
    
@Okx Changed at a cost of 16 bytes. – AdmBorkBork 19 hours ago

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:
|\
| \
|  \
|   \
|    \
|     \
-------
share|improve this answer
    
I apologise for my previous comment, functions are now allowed. – Okx 18 hours ago
    
@Okx No problem. This stands as a full program. I don't think I'll look into the fashion of a function solution :) – TuukkaX 18 hours ago

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
share|improve this answer

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.
share|improve this answer

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 = "")
share|improve this answer
1  
Might want to fix the spelling of ungolfed – LliwTelracs 18 hours ago

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.

share|improve this answer

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.

share|improve this answer
    
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. – Jan 14 hours ago

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

share|improve this answer

Pyth, 23 bytes

Iq0Q.q)VQ++\|*dN\\)*\-h

Test suite available online.

Explanation

Iq0Q.q)VQ++\|*dN\\)*\-h
   Q    Q              Q  Q implicitly appended to program, initializes to eval(input)
              d           d initializes to ' ' (space)
Iq0Q  )                   If 0 == eval(input):
    .q                     Exit the program
       VQ         )       For N in range(0, eval(input)):
             *dN           Repeat space N times
          +\|              Prepend |
         +      \\         Append \
                           Implicitly print on new line
                   *\-hQ  Repeat - 1 + eval(input) times
                          Implicitly print on new line
share|improve this answer

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.

share|improve this answer

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.

share|improve this answer
    
Your function doesn't give correct output for input of 0 – LliwTelracs 16 hours ago
    
@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. – Ismael Miguel 16 hours ago

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
share|improve this answer

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.

share|improve this answer

Common Lisp, 89 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,,,v<~>"(1+ n)#\-)))

Ungolfed

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

I'm sure I could make this shorter somehow.

share|improve this answer

Befunge-98, 68 bytes

&:!#@_000pv<
:kg00 ',|'<|`g00:p00+1g00,a,\'$,kg00
00:k+1g00-'<@,k+1g
share|improve this answer
    
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? – DJMcMayhem 15 hours ago
    
@DJMcMayhem I checked it, the TIO gives k instruction one more execution (executes pop()+1 times). Bug in their implementation. – Uriel Eli 14 hours ago
    
@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) – Andrew Savinykh 14 hours ago

Haskell, 82 bytes

f 1=["\\\n"]
f n|t<-f$n-1=t++[' ':last t]
g 0=""
g n=(f n>>=('|':))++([0..n]>>"-")

Try it online! Usage:

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

Or more nicely:

Prelude> putStr $ g 4
|\
| \
|  \
|   \
-----
share|improve this answer

JavaScript, 66 bytes

f=(x,i=0)=>i<x?`|${" ".repeat(i)}\\\n`+f(x,i+1):"-".repeat(x&&i+1)
share|improve this answer

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.

share|improve this answer

Underload, 58 bytes

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

Assumes the input is a Church numeral on the stack.

Explanation:

This is the main subprogram:

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

It runs this code n times:

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

Stack trace of that code (with 3 on the stack):

       (::**)
(|)    (::**)(|)
S      (::**)          ; printed
:      (::**)(::**)
( )    (::**)(::**)( )
~      (::**)( )(::**)
^      (::**)( )
 :     (::**)( )( )
 :     (::**)( )( )( )
 *     (::**)( )(  )
 *     (::**)(   )
S      (::**)          ; printed
(\ )   (::**)(\ )      ; the space is a newline
S      (::**)          ; printed
(:)    (::**)(:)
~      (:)(::**)
*      (:::**)
(*)    (:::**)(*)
*      (:::***)

All this does is prints the line with counter repeated times and then increments counter. So, running this n times with counter starting at 0 (!()) would print the required lines. The only thing left to do is to print the dashes at the bottom, which is just repetition.

The wrapper around the main subprogram just checks if the input was zero and do nothing if so.

share|improve this answer

8th, 94 bytes

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

Explanation

The word f require 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
   ( "\x20" . ) swap times \ Print space between sides
   "\x5c" . 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

4 f
|\
| \
|  \
|   \
-----
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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