Given an integer, output an upside-down tent.

The input determines both the size of the tent (absolute value) and whether the entrance is on the left side (negative numbers) or the right side (positive numbers).

If input = -1:

If input = -2:
\  /   /

If input = -3:
\    /     /
 \  /     /

If input = 1:

If input = 2:
\   \  /

If input = 3:
\     \    /
 \     \  /

et cetera

Note that the top of the tent (i.e. the last line) has 2 * abs(input) - 1 underscores.

There can be no leading spaces, such that the first line directly starts with an underscore.

Assume that the input will never be 0.

Your code should be as short as possible.

This challenge is based on a chat mini challenge by Helka Homba, which is allowed to be used in real challenges under the conditions of Calvin's Hobbies Public License.

  • 1
    \$\begingroup\$ Are trailing spaces OK? Meaning, can we output four strings of 12 length (a rectangle) for input 3 for example? \$\endgroup\$ – AdmBorkBork Sep 14 '16 at 12:50
  • 1
    \$\begingroup\$ @TimmyD They are allowed. \$\endgroup\$ – user48538 Sep 14 '16 at 12:51
  • 2
    \$\begingroup\$ @TimmyD sure, that one's probably a dupe of something else too, I'm not really sure where the chain starts. I just think we've seen enough of these by now. \$\endgroup\$ – Nathaniel Sep 15 '16 at 13:08
  • 5
    \$\begingroup\$ I fail to see how the questions are even remotely similar. Sure, they're both ascii-art challenges that take an number and have you output the n-th iteration of something, but that's where the similarity ends. If that's enough to close as dupe, we shouldn't take any more ascii-art challenges at all. \$\endgroup\$ – James Sep 15 '16 at 16:25
  • 2
    \$\begingroup\$ @Nathaniel Our accepted guideline for two challenges being duplicates is whether answers from one can be reused (competitively) on the other with little or no modification. Whether challenges bring something novel to the table is not part of that guideline. Please use downvotes for challenges you want to discourage or just ignore them if they don't think they're interesting and let those who do enjoy them. \$\endgroup\$ – Martin Ender Sep 15 '16 at 16:41

16 Answers 16


MATL, 55 53 52 51 bytes

|95cy4*Y"DXytPEt0*yvG0>?P_]!'\/ 'w)95JG|G0<yEq:++&(

Try it online!


Let N denote the input. The code proceeds in three steps.

First, the first line of 4*N underscores is built as a string and is displayed (which removes it from the stack).

Second, the "frame" of the tent is built using the two types of slashes. To do this, a numerical 2D array is created which contains 1 and 2 corresponding to the two types of slashes, and 0 for space.

This is done concatenating four matrices:

  1. An identity matrix of size abs (N);
  2. A matrix of the same size containing 2 in the antidiagonal;
  3. A null matrix of the same size;
  4. A copy of matrix 2.

Concatenating these four matrices vertically gives, using N=3 as an example, the following 4*N × N matrix:

1 0 0
0 1 0
0 0 1
0 0 2
0 2 0
2 0 0
0 0 0
0 0 0
0 0 0
0 0 2
0 2 0
2 0 0

(which, transposed, begins to look like the tent).

We now take care of the sign of the input. If it is positive we simply transpose the above matrix and index into the string '\/ '. Indexing is 1-based and modular, so 1 becomes '\', 2 becomes '/' and 0 becomes ' ', producing the 2D char array

\    /     /
 \  /     / 
  \/     /  

On the other hand, if the input is negative we vertically flip and arithmetically negate the 4*N × N matrix, producing

-2  0  0
 0 -2  0
 0  0 -2
 0  0  0
 0  0  0
 0  0  0
-2  0  0
 0 -2  0
 0  0 -2
 0  0 -1
 0 -1  0
-1  0  0

Index -1 now refers to '/' and -2 to '\'. That is, the two types of slashes have been interchanged, as required. Again transposing and indexing into the string '\/ ' thus gives the reversed tent:

\     \    /
 \     \  / 
  \     \/  

Third, underscores need to be filled into part of the last row of the 2D char array. The horizontal position of this line depends on the sign of the input, and its lenght is abs(N).

Once the corresponding spaces have been replaced by underscores, the result is implicitly displayed, below the initial line of underscores that was already displayed in the first step.

  • \$\begingroup\$ Shouldn't those underscores at the beginning be spaces? \$\endgroup\$ – James Sep 14 '16 at 16:31
  • \$\begingroup\$ @DJMcMayhem Sorry, what do you mean? \$\endgroup\$ – Luis Mendo Sep 14 '16 at 16:50
  • \$\begingroup\$ When I run your code the first line is all underscores. The output zyabin gave doesn't have that. \$\endgroup\$ – James Sep 14 '16 at 16:51
  • \$\begingroup\$ @DJMcMayhem I don't follow. The first line in the test cases is underscores, isn't it? And other answers (not yours) do that too? \$\endgroup\$ – Luis Mendo Sep 14 '16 at 16:54
  • 1
    \$\begingroup\$ @DJMcMayhem :-D Weird indeed. Try a different browser? \$\endgroup\$ – Luis Mendo Sep 14 '16 at 16:59

Javascript (ES6), 139 bytes

Builds the tent recursively:

f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`

Ungolfed and commented

f = (
  N,                                  // N is the original parameter (remains unchanged)
  n = N > 0 ? N : -N,                 // n is initialized to abs(N)
  i = 0,                              // i is the row counter (*2)
  r = (j, i) => ' _'[i||0].repeat(j), // helper function to repeat ' ' or '_' j times
  a = `\\${r(i)}/`,                   // a = '\ /' pattern
  b = r(n*2+i-1, +!i)                 // b = padding pattern filled with ' ' or '_'
) =>
  n-- ?                               // if we haven't made it yet to the top row:
    f(N, n, i+2) + `\n` +             //   - compute next row(s) / append line break
    r(n) +                            //   - append leading spaces
    (N < 0 ? a+b+'/' : '\\'+b+a)      //   - append a/b patterns according to N sign
  :                                   // else:
    r(i*2, 1)                         //   - return top row, made of '_' characters


var f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`



Python 2, 143 141 139 138 137 bytes

-2 bytes thanks to @Sp3000 (no need to parenthesise exec in Python 2)
-1 byte thanks to @Sp3000 (use cmp)

def f(n):d=cmp(n,0);a,b='\/'[::-d];s=n*d;x=2*s-1;y=4*s;print'_'*y;i=0;exec"print' '*i+(b+' '*(y-3-x-i-i)+a+'_ '[s-i>1]*x+a)[::d];i+=1;"*s

Test it at ideone

First we see if n is negative and make d +1 if it is and -1 if not.
Then we select the two slashes, a and b, using d such that a='\', b='/' when n is positive and a='/', b='\' when n is negative.
Next we set s=abs(n) which may be achieved by s=n*d.
Then we calculate the number of _ at the top (bottom of the picture), which is also the number of in the side of the tent as x=2*s-1.
Then we calculate the number of _ at the base of the tent (top of the picture), and store it as y=4*s since it will be used in the loop to create the rest of the tent.
Now we print the base of the tent using print'_'*y.
Then we print the rest of the tent by executing s print statements with a looping variable i initialised to 0 which increments by 1 for each print statement.
The rest of the tent then has y-3-x-i-i spaces in the door and x spaces in the body until the top is reached, when s-i>1 evaluates to False, picking the _ from '_ '.
For a positive, left-door, tent the whole of the tent, excluding the leading spaces is back-to-front, so it is reversed while the positive, 'right-door', tent is not with [::d].

  • \$\begingroup\$ @Sp3000 unfortunately cmp(0,0) returns 0 \$\endgroup\$ – Jonathan Allan Sep 14 '16 at 15:44

Python 2, 121 bytes

def f(n):i=k=abs(n);print'_'*k*4;exec"print' '*(k-i)+r'\\\%%s%\*%c%%*sc/'[n<0::2]%(' _'[i<2]*(2*k-1))%(2*i-1,47);i-=1;"*k

Just a lot of string formatting.


C#, 215 214 bytes

string t(int N){var n=N<0;N=n?-N:N;var t=new string('_',4*N);for(int i=0;i<N;){string f=new string(i<N-1?' ':'_',2*N-1),p=new string(' ',2*N-2*i-2);t+='\n'+new string(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

There's a possibility to save a few bytes when using using s=string; beforehand.

s t(int N){var n=N<0;N=n?-N:N;var t=new s('_',4*N);for(int i=0;i<N;){s f=new s(i<N-1?' ':'_',2*N-1),p=new s(' ',2*N-2*i-2);t+='\n'+new s(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

which would be 15 (using) + 184 (method) = 199 bytes.

  • 5
    \$\begingroup\$ Welcome to PPCG, BackFromExile! \$\endgroup\$ – Erik the Outgolfer Sep 15 '16 at 15:14
  • \$\begingroup\$ Indeed, welcome to PPCG! A very nice first answer +1. I tried to find anything to golf (quite a while since I programmed in C#), and in the end was only able to find one thing for -1 byte: If you change the first var inside the for-loop to string, you can remove the second var (including space to save the byte). So var f becomes string f, and ;var p= becomes ,p=. \$\endgroup\$ – Kevin Cruijssen Sep 16 '16 at 11:38

TSQL, 195 bytes


DECLARE @b INT=ABS(@),@i INT=0PRINT REPLICATE('_',4*@b)z:SET @i+=1PRINT SPACE(@i-1)+'\'+STUFF(REPLICATE(IIF(@i<@b,' ','_'),4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))+'/'IF @i<@b GOTO z




  SET @i+=1
    +STUFF(REPLICATE(IIF(@i<@b,' ','_'),
IF @i<@b GOTO z



V, 66 bytes

é /ä
"aDoÀñá_>ñ^hr\A\/ò^hÄX$2é_Ó_/ òÄÒ_ñ/-
ddÍܨ[ _]*©Ü¨ *©/ܲ¯±

Try it online!

This is a pretty naive approach, so I'll try to golf it down further later today. This solution contains unprintable characters, so here is a hexdump:

0000000: e920 2fe4 0a22 6144 6f1b c0f1 e15f 3ef1  . /.."aDo...._>.
0000010: 5e68 725c 415c 2f1b f25e 68c4 5824 32e9  ^hr\A\/..^h.X$2.
0000020: 5fd3 5f2f 20f2 c4d2 5ff1 2f2d 0a64 64cd  _._/ ..._./-.dd.
0000030: dca8 5b20 5f5d 2aa9 dca8 202a a92f dcb2  ..[ _]*... *./..
0000040: afb1                                     ..

05AB1E, 52 bytes



                                                     # implicit input, call this A
Ä©                                                   # store abs(A) in register for later use
  '_4®*×,                                            # print 4*A underscores (tent floor)
         F                                           # for each non-floor section in range(N)
          Nð×'\                                      # push N spaces at the beginning of the 
                                                     # row followed by a backslash
                  N>®Qi'_ëð}                         # if we're on the last row push an
                                                     # underscore, else a space
               ®·<          ×                        # repeat that char abs(A)*2-1 times
                             ®N>-·ð×                 # push 2*(abs(A)-(N+1)) spaces
                                    ®¹Qi'\ës'/}      # if input is positive push backslash
                                                     # else push a slash
                                               s'/   # move that char between the 2 sections
                                                     # of spaces
                                                  J, # join the row and print

Try it online!


PowerShell v2+, 217 205 190 187 184 bytes

((($x=1..$a|%{($w=" "*($_-1))+$z+" "*(2*($a-$_))+$y+(' ','_')[$_-eq$a]*($a*2-1)+$y+$w})|%{-join$_[($a*4)..0]}),$x)[$b]

Takes input $b as an integer. Note that if $b is negative, you need to explicitly surround it with parens to cast it appropriately (see examples), else PowerShell will think it's a string.

Regardless of which direction the tent is facing, the first line is the same, a bunch of underscores; exactly 4*abs(input) many of them, actually. That number is also stored into $a for use later. Additionally, now that we have the absolute value of $b stored into $a, we turn $b into a Boolean for its sign, and choose our slashes stored into $y and $z.

The next line is constructing and formulating the output, and it's a doozy, so let's break it down.

We're essentially indexing into an array of two elements, (big long calculations saved into $x) or $x, based on $b.

The calculations are where the tent body is constructed. We loop from 1..$a|%{...}. Each iteration we're constructing a line of the tent body. We start with a number of spaces equal to the line # we're on -1, so that it's appropriately left-aligned. That's stored into $w for later, and concatenated with the appropriate slash ($z, based on $b), then the doorframe number of spaces, then the other slash $y, then either underscores or spaces depending upon if we're on the bottom line or not, then another slash $y, and finally the appropriate number of trailing spaces ($w) to construct a rectangular string. That resulting array of strings is stored into $x.

If the left half of the array is selected (i.e., $b is False since the input was positive), then we need to loop through $x and reverse each line item -- this is where the trailing spaces come into play; it allows us to simply reverse the lines rather than re-calculate distances.

If $b is True, then the right half of the array $x is selected instead.

In either case, the pipeline now contains an array of strings. Implicit output via Write-Output happens at program completion, with default newline between elements.


PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (-5)
\        /         /
 \      /         / 
  \    /         /  
   \  /         /   

PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (4)
\       \      /
 \       \    / 
  \       \  /  

Haskell, 187 184 183 bytes

f x=unlines$[(n*4)%'_']++((' '#)<$>[0..n-2])++['_'#(n-1)]where m#i=i%' '++'\\':m!i++"/";m!i|x>0=(2*n-1)%m++'\\':(2*(n-i-1))%' '|q<-2*(n-i-1)=q%' '++'/':(2*n-1)%m;n=abs x;m%c=c<$[1..m]

I feel like this is not a great score for Haskell, so any ideas for improvement are welcome.


tent :: Int -> String
tent x = unlines $ [replicate (n*4) '_'] ++ (row ' '<$>[0..n-2]) ++ [row '_' (n-1)]
    where row m i = replicate i ' ' ++ "\\" ++ dir m i ++ "/"
          -- direction selector
          dir m i | x > 0 = side m ++ "\\" ++ entrance i ' '
                  | 1 > 0 = entrance i ' ' ++ "/" ++ side m
          side = replicate (2*n-1)
          entrance i = replicate (2*(n-i-1))
          n = abs x
  • \$\begingroup\$ Better than my 290 bytes I was about to post... \$\endgroup\$ – Myridium Sep 14 '16 at 21:25
  • \$\begingroup\$ Should you not add a main so that it accepts stdin as the input? \$\endgroup\$ – Myridium Sep 14 '16 at 21:27
  • \$\begingroup\$ You can post a single function unless the question specifies otherwise. There's a meta thread for the general rules on answering, I'll try to find it for you. \$\endgroup\$ – sudee Sep 14 '16 at 21:33
  • 1
    \$\begingroup\$ You can save 2 bytes by changing where you prepend a single character to use the : character. i.e. change "\\" ++ entrance... to '\\':entrance. \$\endgroup\$ – Myridium Sep 14 '16 at 21:58
  • 1
    \$\begingroup\$ Don't waste the "otherwise" guard: you can change |1>0=(2*(n-i-1))%' ' to |q<-2*(n-i-1)=q%' '. \$\endgroup\$ – nimi Sep 14 '16 at 22:38

C, 240 207 193 Bytes

#define P putchar

This time I optimized the function g(...) to use a single for loop.

#define P putchar

This time macro X is better off as a function g(...) and since y and z are parameters in a new scope I can just decrement them in the scope of g.

#define P putchar
#define X(x,y,z){for(k=0;k++<y;P(l?32:95));P(x);for(k=0;k++<z;P(l?32:95));}
a,i,j,k,l,m;f(n){for(l=a=abs(n);i++<a*4;P(95));j=2*a-1;P(10);while(l--){for(m=a;--m>l;P(32));P(92);if(n>0)X(92,j,l*2)else X(47,l*2,j)puts("/");}}

Test with this main function; This should golf down much smaller.


C# 241 231 Bytes

Saved 10 bytes thanks to @Kevin Cruijssen

using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;}

Old version:

string f(int N){var f=N<0;N=N>0?N:-N;var o=new string('_',N*4);for(int j=0;j<N;){int z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new string(' ',j)+'\\'+new string(' ',z)+(f?'/':O)+new string(O,j++*2)+(f?O:'\\')+new string(' ',z)+'/';}return o;}

Originally had the new string(...) as a Func<char,int,string> but saved one byte using the constructor. I wish int->char was implicit

Pretty sure my math can be fixed somehow too, but I can't see it

  • 1
    \$\begingroup\$ You can golf it some more. First of all you can remove the int before z= by adding it to the for-loop: int j=0,z. And since you use string quite a lot, you can alias it with using s=System.String; So the total becomes: using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;} (231 bytes) \$\endgroup\$ – Kevin Cruijssen Sep 16 '16 at 11:52

Swift 2.2 421 bytes

Well... This was an attempt.


let t={(s:String,n:Int)->String in return String(count:n,repeatedValue:Character(s))};let e={(n:Int)in var w=[String]();w.append(t("_",abs(n)*4));let c = abs(n);let d = n>0 ? "/": "\\";let f = n>0 ? "\\": "/";for var i in 0...abs(n)-1 {w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));};w=n<0 ?w:w.map(){String($0.characters.reverse())};print(w.joinWithSeparator("\n"))}


let t={(s:String,n:Int) -> String in
    return String(count:n,repeatedValue:Character(s))
let e={(n:Int) in
    var w=[String]();
    let c = abs(n);
    let d = n>0 ? "/": "\\";
    let f = n>0 ? "\\": "/";
    for var i in 0...abs(n)-1 {
        w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));
    w=n<0 ?w:w.map(){String($0.characters.reverse())};

PHP, 143 bytes

$t=str_repeat;echo$t(_,4*$s=$k=abs($n=$argv[1]));for(;$k--;$p.=" "){$f=$t("  ",$k);$r=$t($k?" ":_,2*$s-1);echo"

run with php -r '<code>' <parameter>


$t=str_repeat;  // function name to variable saves 10-1 bytes
echo$t(_,4*$s=$k=abs($n=$argv[1])); // print bottom
    $k--;   // $k from abs($n-1) to 0
    $p.=" "                 // create padding
    $f=$t("  ",$k);         // create front
    $r=$t($k?" ":_,2*$s-1); // create side/roof
        ?"$f/$r/"   // print, entrance left
        :"$r\\$f/"  // print, entrance right

Batch, 289 bytes

@echo off
set u=
for /l %%i in (2,1,%n:-=%)do call set u=_%%u%%_
echo _%u%__%u%_
set l=
set m=%u%/_%u%
if %n% gtr 0 set m=%u%_\%u%
set m=%m:_= %
for /l %%i in (2,1,%n:-=%)do call:l
set m=%m: =_%
echo %l%\%m%/
set l= %l%
if %n% gtr 0 set m=  %m:~0,-2%
set m=%m:~2%

Takes input on STDIN. Starts by creating a string of 2*(abs(n)-1) underscores. This is then repeated plus an additional 4 underscores for the base of the tent. The rest of the tent then consists of an indent (which increases by 1 on each line), a \, the middle of the tent, and a /. The middle of the tent starts as 2*(abs(n)-1) spaces, plus either \ or / plus a space (which I can't represent in Markdown), plus another 2*(abs(n)-1) spaces. I reuse the underscore string and change them to spaces for convenience, but then change the spaces back to underscores for the last line. Each line removes two spaces from one side of the middle of the tent, although it's slightly golfier to move the two spaces to the start of the string first if necessary.


Canvas, 25 bytes


Try it here!


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.