30
\$\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\$
  • 4
    \$\begingroup\$ Does it need to be a program or can it be a function? \$\endgroup\$ – fəˈnɛtɪk Feb 8 '17 at 15:04
  • 7
    \$\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\$ – Kritixi Lithos Feb 8 '17 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\$ – fəˈnɛtɪk Feb 8 '17 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\$ – Stewie Griffin Feb 8 '17 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\$ – 12Me21 Feb 8 '17 at 18:25

54 Answers 54

0
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ You can do -~c*(c>0) on the last line to save 3 bytes :) \$\endgroup\$ – Yytsi Feb 9 '17 at 17:58
  • \$\begingroup\$ Or better yet: c and-~c. \$\endgroup\$ – Yytsi Feb 10 '17 at 17:42
0
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ @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. \$\endgroup\$ – Ismael Miguel Feb 8 '17 at 19:07
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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.

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

Befunge-98, 68 bytes

&:!#@_000pv<
:kg00 ',|'<|`g00:p00+1g00,a,\'$,kg00
00:k+1g00-'<@,k+1g
\$\endgroup\$
  • \$\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\$ – DJMcMayhem Feb 8 '17 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\$ – Uriel Feb 8 '17 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\$ – Andrew Savinykh Feb 8 '17 at 21:10
0
\$\begingroup\$

JavaScript, 66 bytes

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

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.

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

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.

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

Ruby, 48 bytes

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

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.
\$\endgroup\$
0
\$\begingroup\$

bash + Unix utilities, 71 bytes

(($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
|\
| \
|  \
|   \
|    \
------
\$\endgroup\$
0
\$\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\$
0
\$\begingroup\$

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.

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

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+"-")
\$\endgroup\$
  • \$\begingroup\$ Can you do var a=5,b=""; in Swift? \$\endgroup\$ – Kritixi Lithos Feb 14 '17 at 12:17
  • \$\begingroup\$ Yes its possible \$\endgroup\$ – Leena Feb 14 '17 at 12:18
  • \$\begingroup\$ Also can't you do print(b+"-") instead of b+="-";print(b)? \$\endgroup\$ – Kritixi Lithos Feb 14 '17 at 12:20
  • \$\begingroup\$ I guess now its perfect \$\endgroup\$ – Leena Feb 14 '17 at 12:27
  • \$\begingroup\$ Also var a=5,b="",d;for c in 0..<a{d="|" instead of the beginning of the loop if it works \$\endgroup\$ – Kritixi Lithos Feb 14 '17 at 12:29
0
\$\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\$
0
\$\begingroup\$

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

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

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
|\
| \
|  \
|   \
-----
\$\endgroup\$
0
\$\begingroup\$

Python 3, 61 bytes

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

Try it online!

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

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

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

Try it online!

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

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

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

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
\$\endgroup\$
0
\$\begingroup\$

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)
\$\endgroup\$
  • \$\begingroup\$ You can drop this down to 65 bytes For i=0To[A1-1]:?"|"String(i,32)"\":Next:If i Then?String(i+1,45) \$\endgroup\$ – Taylor Scott Dec 18 '17 at 18:22
0
\$\begingroup\$

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!

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

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
\$\endgroup\$

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.