47
\$\begingroup\$

Write a program or function that takes in a positive integer (via stdin, command line, or function arg) and prints or returns a string of that many of these small triangles tiled together, alternating which way they point:

 /\
/__\

This sole triangle is the output if the input is 1.

If the input is 2, the output is

  ____
 /\  /
/__\/

If the input is 3, the output is

  ____
 /\  /\
/__\/__\

If the input is 4, the output is

  ________
 /\  /\  /
/__\/__\/

And so on. Your program must support inputs up to 216 - 1 = 65535.

Details

  • The leftmost triangle always points upwards.
  • There may be trailing spaces but there may not be unnecessary leading spaces.
  • There may be an optional trailing newline.
  • Note that for 1 the output is two lines long but otherwise it's three. This is required.
  • The shortest submission in bytes wins.
\$\endgroup\$

32 Answers 32

32
\$\begingroup\$

Pyth, 44 42

ItQpdd*\_*4/Q2)jbms<*dQhQ,c" /\ "2,\/"__\\

The first line:

ItQpdd*\_*4/Q2)
ItQ           )    If the input is not 1
   pdd             Print two spaces
      *\_*4/Q2     Then groups of 4 underscores, repeated input/2 times.

The other two lines are generated by noticing that the second line consists of " /" and "\ " alternating input + 1 times, and the third line consists of "/" and "__\" alternated in the same fashion.

\$\endgroup\$
  • 160
    \$\begingroup\$ striked out 44 is still normal 44 :( \$\endgroup\$ – Optimizer Mar 24 '15 at 8:22
  • 4
    \$\begingroup\$ 42. Of course! \$\endgroup\$ – mbomb007 Mar 24 '15 at 21:17
  • 49
    \$\begingroup\$ @Optimizer: I find it endlessly amusing that your sadness over the appearance of 44 has received more votes than the question or this answer. \$\endgroup\$ – Alex A. Mar 27 '15 at 14:23
  • 6
    \$\begingroup\$ Just got 10 answers deep in the crossed out 44 chain \$\endgroup\$ – Leo May 30 '17 at 9:08
  • 3
    \$\begingroup\$ @AlexA. I find it endlessly amusing that your amusement over Optimizer's sadness over the appearance of 44 has received more votes than the question or this answer. \$\endgroup\$ – isaacg Jan 11 at 23:43
24
\$\begingroup\$

SQL, 182 175 173 187 bytes

Not that this'll ever be the shortest, but it's still amusing to try to minimize sql ;) lol I did this in Oracle 11, however, these should be basic SQL. [edit] as pointed out, I didn't apply the when input = 1 rule - only show 2 lines. can't think of a better way to do it, however, I did save a couple bytes by modifying the v logic ;) adding 2 ahead of time saves a couple bytes by not having to repeat it later [/edit]

select decode(&i,1,'',rpad('  ',v,'____')||z)||rpad(' /',v,'\  /')||decode(y,1,'\')||z||rpad('/',v-1,'__\/')||decode(y,1,'__\')from(select 2+floor(&i/2)*4v,mod(&i,2)y,chr(10)z from dual);

[edit1] removed some unnecessary spaces[/edit1] [edit2] changed &&i to just &i. It cuts down 2 chars, but forces user to input the # of triangles twice ... :P I realized my "good coding habits" using &&i were costing be 2 bytes!! The horror!! [/edit2]

Explanation (note: I use &&1 in this explanation so it only prompts once, the &1 above saves code space, but prompts multiple times ;) )

 select  -- line 1
     decode(&&1,1,'',   -- don't need line 1 if input is 1
     rpad('  ',v,'____') || z ) || -- every pair of triangles
     -- line 2
     rpad(' /',v,'\  /') ||  -- every pair of triangles
          decode(y,1,'\') || z || -- add the final triangle, input: 1,3,5 etc.
     -- line 3
     rpad('/',v-1,'__\/') ||  -- every pair of triangles
          decode(y,1,'__\')   -- add the final triangle, input: 1,3,5 etc.
from (select 2+floor(&&i/2)*4 v,   -- common multiplier. 4 extra chars for every triangle pair
             mod(&&i,2) y,  -- Flag for the final triangle (odd inputs, 1,3,5, etc)
             chr(10) z  -- CR, here to save space.
        from dual);

Output

  SQL> accept i
  1
  SQL> /

   /\
  /__\


  SQL> accept i
  2
  SQL> /

    ____
   /\  /
  /__\/


  SQL> accept i
  3
  SQL> /

    ____
   /\  /\
  /__\/__\


  SQL> accept i
  12
  SQL> /

    ________________________
   /\  /\  /\  /\  /\  /\  /
  /__\/__\/__\/__\/__\/__\/


  SQL>
\$\endgroup\$
  • 1
    \$\begingroup\$ Would it work to remove the space after from? If so that'll save you a byte. \$\endgroup\$ – Alex A. Mar 25 '15 at 18:54
  • \$\begingroup\$ oh good lord .. that's nuts . just tried it .. and then "went to town" stripping out what spaces I could ... O.o This sucker's unreadable now .. but it works still ;) lol (I can NOT believe the aliases still work like that .. O.o hehe ) \$\endgroup\$ – Ditto Mar 27 '15 at 12:46
  • \$\begingroup\$ I'm sooo confused on the upvotes! O.o It's nowhere near the smallest size .. yet .. upvotes! O.o wow. \$\endgroup\$ – Ditto Mar 27 '15 at 13:09
  • 2
    \$\begingroup\$ Upvotes typically denote that people like your submission because it's creative, the language used is uncommon, or any number of reasons. In my experience it's uncommon for the shortest code golf answer to also be the highest voted. So while this may not be the shortest answer, the community has deemed it a good one. :) \$\endgroup\$ – Alex A. Mar 27 '15 at 14:21
  • \$\begingroup\$ @Alex .. cool, gravy :) (i'm gonna have to try this in Excel next ... lol ) \$\endgroup\$ – Ditto Mar 27 '15 at 14:54
11
\$\begingroup\$

Python 2, 89 88 87 85 83 named / 81 unnamed

f=lambda n:1%n*("  "+n/2*4*"_"+"\n")+(" /\ "*n)[:2+2*n]+"\n"+("/__\\"*n)[:n-~n+n%2]

(Thanks to @orlp for a byte, and @xnor for another three)

This is a function which takes in an int n and returns the triangles as a string using the row-by-row approach.

e.g. print f(10) gives

  ____________________
 /\  /\  /\  /\  /\  /
/__\/__\/__\/__\/__\/

For the first row, instead of (n>1)* we use 1%n*, since 1%n is 0 if n == 1 and 1 if n > 1.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can shave off a character, turning " /\\ " into " /\ ". \$\endgroup\$ – orlp Mar 24 '15 at 15:37
  • \$\begingroup\$ Doesn't this lambda work in Python 3 also? \$\endgroup\$ – mbomb007 Mar 24 '15 at 21:21
  • 2
    \$\begingroup\$ @mbomb007 There's a floor division in there \$\endgroup\$ – Sp3000 Mar 24 '15 at 23:01
  • \$\begingroup\$ @orlp Allow me now, to add further confusion, but deleting my comment ;) \$\endgroup\$ – FryAmTheEggman Mar 25 '15 at 0:16
  • \$\begingroup\$ I'm suspicious of the "\n".join() for 3 items, even if the list is used to conditionally remove the first element. Perhaps something like b*(x+"\n")+y+"\n"+z is shorter? \$\endgroup\$ – xnor Mar 25 '15 at 3:16
7
\$\begingroup\$

JavaScript (ES6), 101 109

Way too long

f=(n,z=a=>a.repeat(n/2))=>(n>1?'  '+z('____')+'\n ':' ')+z('/\\  ',w=' /'[++n&1]+'\n')+w+z('/__\\')+w

Explanation

Using fat arrow for function definition. Moreover no {} block: the function body is a single expression that is the return value. f=(a,b,c)=>expr is equivalent to

function f(a,b,c)
{
  return expr;
}

Inside a single expression you can not use statements like if or var, but

  • parameters with default values can be used as local variables
  • conditional expressions ?: work well instead of if else
  • you can add more subexpressions using the comma operator or even better as unused parameter to functions. In this case the assignment of w is the second (unused) parameter to the function z

We can rewrite the f function as

f = function(n) {
  var z = function(a) { // use current value of n (that changes)
    return a.repeat(n/2);
  };
  var result;
  if (n > 1) {
    result = '  ' + z('____') + '\n '; // top row if more than 1 triangle
  else
    result = ' '; // else just the blank
  ++n; // increase n, so invert even/odd
  w = ' /'[n&1]+'\n'; //  blank if n is now even, else '/' if n is now odd
  // the next rows will end in "/\" or "\  /" based on n even/odd
  result +=  z('/\\  ') + w; // offset by the blank char added before
  result += z('/__\\') + w;
  return result;
}

Test in Firefox/FireBug console

console.log(f(1),f(2),f(3),f(4),f(9))

Output

 /\   
/__\ 

  ____
 /\  /
/__\/

  ____
 /\  /\   
/__\/__\ 

  ________
 /\  /\  /
/__\/__\/

  ________________
 /\  /\  /\  /\  /\   
/__\/__\/__\/__\/__\ 
\$\endgroup\$
  • \$\begingroup\$ Nicely done! I spent far too long yesterday looking to shorten it and at best managed to reproduce the 109 in different ways. -8 is quite the jump. \$\endgroup\$ – DocMax Mar 25 '15 at 19:06
  • \$\begingroup\$ Cool. Could you post an explanation? I don't fully understand the use of w \$\endgroup\$ – BadHorsie Mar 30 '15 at 15:54
  • \$\begingroup\$ @BadHorse explanation added (really, this time) \$\endgroup\$ – edc65 Mar 31 '15 at 6:35
  • \$\begingroup\$ Out of interest I tried to do it without trailing spaces and came up with n=>(n>1?' '+'____'.repeat(n/2)+'\n':'')+' /\\ '.repeat(n).slice(0,n*2+2-n%2)+'\n'+'/__\\'.repeat(n).slice(0,n*2+1+n%2) for 119 (deliberately not using template strings etc. to match your answer). \$\endgroup\$ – Neil Jan 13 at 14:29
6
\$\begingroup\$

CJam, 55 53 51 bytes

SSri:I2/4*'_*N]I1>*" /\ "I*I)2*<N"/__\\"I*I2*)I2%+<

I tried porting my Python answer and it turned out to be shorter than the other CJams.

Permalink.

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

Haskell 155 153 139 131 Bytes

I found a slightly different approach that turned out to be shorter than my original method. My original attempt is preserved below. As with before, golfing tips are appreciated.

m n=unlines.dropWhile(=="  ").z["  "," /","/"].foldr1 z$map t[1..n]
t n|odd n=["","\\","__\\"]
t _=["____","  /","/"]
z=zipWith(++)

Thanks to Nimi for the golfing tips.


Previous Attempt 197 179 Bytes

t n=putStr.unlines.dropWhile(all(==' ')).z(flip(++))(if odd n then["","\\","__\\"]else repeat"").z(++)["  "," /","/"].map(take(4*div n 2).cycle)$["____","\\  /","__\\/"]
z=zipWith
\$\endgroup\$
  • 4
    \$\begingroup\$ Some hints for golfing: (mod n 2)==0 is even n or better use odd n and swap the then and else part. concat.take(div n 2).repeat is take(4*div n 2).cycle because all list elements are of length 4. Assign short names to functions with long names, e.g. z=zipWith - then use z. You can kick out a few spaces ...repeat""else[.... \$\endgroup\$ – nimi Mar 24 '15 at 18:35
  • \$\begingroup\$ @nimi Thanks for your hints! Using them, I was able to golf my original solution to 179 bytes. By reconsidering my approach, I was also able to reduce my solution to 155 Bytes. \$\endgroup\$ – ankh-morpork Mar 25 '15 at 0:46
  • 1
    \$\begingroup\$ Hints, part II: foldr z["","",""] is foldr1 z, because the list to fold is never empty. Instead of all(==' ') you can use ==" " (<- two spaces in-between), because it is used to remove the empty line in case of n = 1 and here the first line is " ". The first definition of t can be written in a single line: t n|odd.... \$\endgroup\$ – nimi Mar 25 '15 at 16:15
4
\$\begingroup\$

CJam, 73 68 63 62 60 bytes

This definitely needs some golfing...

S2*l~:I2/'_4**N]I(g*S"\\  /"'\{I2md@*@@*'/\@}:F~N"__\\/"_W<F

Test it here.

Explanation

"Print the first line:";
S2*l~:I2/'_4**N]I(g*

S2*                  "Push a string with 2 spaces.";
   l~:I              "Read and eval the input, store it in I.";
       2/            "Divide by two to get the number of top segments.";
         '_4**       "Push '____' and repeat it by the number of segments.";
              N]     "Push a newline and wrap everything in an array.";
                I(g* "Get sign(I-1) and repeat the array that often. This is a no-op
                      for I > 1 but otherwise empties the array.";

"Print the other two lines. The basic idea is to define block which takes as arguments
 a repeatable 4-character string as well as another string which only gets printed for
 even I.";
S"\\  /"'\{I2md@*@@*'/\@}:F~N"__\\/"_W<F

S                                        "Push a space.";
 "\\__/"'\                               "Push the string '\__/' and the character \.";
          {             }:F~             "Store this block in F and evaluate it.";
           I2md                          "Get I/2 and I%2 using divmod.";
               @*                        "Pull up the second argument and repeat it I%2
                                          times. This turns it into an empty string for
                                          even I.";
                 @@                      "Pull up I/2 and the 4-character string.";
                   *                     "Repeat the string I/2 times.";
                    '/\@                 "Push a / and reorder the three line parts.";
                            N            "Push a newline.";
                             "__\\/"_W<F "Call F again, with '__\/' and '__\'.";
\$\endgroup\$
4
\$\begingroup\$

Julia, 115 bytes

n->(m=n÷2;p=println;k=n%2>0?m+1:m;e=m<k?"":"/";t=" /\\ ";b="/__\\";if n>1 p("  "*"_"^4m)end;p(t^k*" "*e);p(b^k*e))

This creates an unnamed function which accepts an integer and prints the triangles. To call it, give it a name, e.g. f=n->(...).

Ungolfed + explanation:

function f(n)

    m = n ÷ 2                    # Number of upside down triangles
    p = println                  # Store println function to save space
    k = n % 2 > 0 ? m + 1 : m    # Number of right side up triangles
    e = m < k ? "" : "/"         # n even? End lines with a /

    # Top of the triangle
    t = " /\\ "

    # Bottom of the triangle
    b = "/__\\"

    # Print the bottoms of any upside down triangles
    # * performs string concatenation
    # ^ performs string repetition
    if n > 1
        println("  " * "_"^4m)
    end

    # Print the triangle tops (these have two trailing spaces
    # if the last triangle isn't upside down)
    println(t^k * " " * e)

    # Print the triangle bottoms
    println(b^k * e)
end

Example output:

julia> for i = 1:10 f(i) end
 /\  
/__\
  ____
 /\  /
/__\/
  ____
 /\  /\  
/__\/__\
  ________
 /\  /\  /
/__\/__\/
  ________
 /\  /\  /\  
/__\/__\/__\
  ____________
 /\  /\  /\  /
/__\/__\/__\/
  ____________
 /\  /\  /\  /\  
/__\/__\/__\/__\
  ________________
 /\  /\  /\  /\  /
/__\/__\/__\/__\/
  ________________
 /\  /\  /\  /\  /\  
/__\/__\/__\/__\/__\
  ____________________
 /\  /\  /\  /\  /\  /
/__\/__\/__\/__\/__\/

I'm pretty bummed that this is so long. I'm sure there are golfing opportunities aplenty but they aren't clear to me at the moment. Let me know if you have any suggestions or if you'd like any further explanation!

\$\endgroup\$
3
\$\begingroup\$

CJam, 68 62 60 bytes

As far as I can see, this is a completely different approach than the other CJam solution. This can be golfed a lot.

"/__\\ /\\"4/]ri:R(['/"  /"'_4*"__\\"'\L]3/R*<+zR1>SS+*\W%N*

Try it online here

\$\endgroup\$
3
\$\begingroup\$

C# 190

void f(int n){string s=(n>1)?"\n  ":"",t=" /",u = "/";bool b=true;int m=n;while(m-->0){s+=(n>1&&b&&m>0)?"____":"";t+=b?"\\":"  /";u+=b?"__\\":"/";b=!b;}Console.Write("{0}\n{1}\n{2}",s,t,u);}

Ungolfed

void f(int n)
{
string s = (n > 1) ? "\n  " : "", t = " /", u = "/";
bool b = true;
int m = n;
while(m-->0)
{
s += (n > 1 && b && m>0) ? "____" : "";
t += b ? "\\" : "  /";
u += b ? "__\\" : "/";
b = !b;
}
Console.Write("{0}\n{1}\n{2}",s,t,u);
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice work! Note that it is never better to use a whileloop, rather use a for loop. In this case you can save 2 bytes by including the definition of m in the for loop initialisation, and b=!bin the last thing whatever it's called. You can also make savings by replacing string and bool with var. You also don't need the "()" around n>1 clauses, and in the s+= clause you can use the non-short circuiting & rather than && as there are no side-effects or dereferences to go wrong. Finally, 1>0 is shorter than true ;) \$\endgroup\$ – VisualMelon Mar 27 '15 at 10:19
3
\$\begingroup\$

C#, 257183 bytes

void C(int t){int i;var n="\r\n";var s="  "+string.Join("____",new string[1+t/2])+n;for(i=0;i++<=t;)s+=i%2<1?"\\ ":" /";s+=n;for(i=0;i++<=t;)s+=i%2<1?"__\\":"/";Console.WriteLine(s);}

Edit: Thanks to the tips from @VisualMelon, saved 74 bytes.

I know it's far from the best language to golf in, but I'm mostly interested in learning about the various nuances of C#, rather than winning the competition. This is basically a port of this Pyth answer.

I'm thinking the for loops could be golfed further, but I'm not quite sure how, given the tertiary statements embedded within them.

Example (1, 2, 3, 10):

 /\   
/__\  
  ____
 /\  /
/__\/
  ____
 /\  /\ 
/__\/__\
  ____________________
 /\  /\  /\  /\  /\  /
/__\/__\/__\/__\/__\/

Ungolfed:

void C2(int t)
{
    int i;
    var n="\r\n";
    var s="  "+string.Join("____",new string[1+t/2])+n;
    for(i=0;i++<=t;)
        s+=i%2<1?"\\ ":" /";
    s+=n;
    for(i=0;i++<=t;)
        s+=i%2<1?"__\\":"/";
    Console.WriteLine(s);
}
\$\endgroup\$
  • \$\begingroup\$ While StringBuilders are fast and lovely, if you want a low byte count, s+= is your friend. Indeed, you're for loops can be made a bit more compact. The joy/horror of the ++ and -- operators means you can do most of the work in the conditional check for(i=0;i++<=t;) (this checks if i is less than or equal to t then increments it). You'd do well to define the int i outside the for loop, and reuse it, and since you can guarantee that i will never be negative, i%2==0 can be swapped for i%2<1. With these changes, a sub 200byte score is easily attained. \$\endgroup\$ – VisualMelon Mar 27 '15 at 10:35
  • 1
    \$\begingroup\$ Also, I suspect you wrote this up in LINQPad or similar, because access to Enumerable usually requires a using System.Linq directive, and I think it's generally intended that such clauses are included. However, in this instance the only LINQ can be replaced with var s=" "+string.Join("____",new string[1+t/2])+n; which contains no LINQ, and is shorter than the current code ;) It joins lots of null strings together with what we really care about, "____" (the 1+t/2 being because we need another null string to fit another "____" before). The variable n is declared as "\r\n". \$\endgroup\$ – VisualMelon Mar 27 '15 at 10:43
  • \$\begingroup\$ Great tips! I forgot that Enumerable would need System.Linq, I barely pay attention these days. The for loop tip is handy! \$\endgroup\$ – Trent Mar 29 '15 at 23:53
  • \$\begingroup\$ A bit late, but you could save 4 bytes by using Console.Write instead of Console.WriteLine \$\endgroup\$ – Metoniem Feb 9 '17 at 8:09
2
\$\begingroup\$

Java, 185

String f(int n){int i;String s="";if(n>1){s="  ";for(i=0;i<n/2;i++)s+="____";s+='\n';}for(i=0;i<=n;)s+=i++%2<1?" /":"\\ ";s+='\n';for(i=0;i<=n;i++)s+=i%2<1?i<n?"/_":"/":"_\\";return s;}

Explanation

String f(int n) {
    int i;
    String s = "";
    if (n > 1) {
        s = "  ";
        for (i = 0; i < n / 2; i++) {
            s += "____";
        }
        s += '\n';
    }
    for (i = 0; i <= n; i++) {
        s += i % 2 < 1 ? " /" : "\\ ";
    }
    s += '\n';
    for (i = 0; i <= n; i++) {
        s += i % 2 < 1 ? i < n ? "/_" : "/" : "_\\";
    }
    return s;
}
\$\endgroup\$
2
\$\begingroup\$

C# - 151 146 141 138

Inspired by @bacchusbeale's answer

string f(int n){string t="\n",s=n>1?"  "+new string('_',n/2*4)+t:"";for(var b=n<0;n-->=0;t+=b?"__\\":"/",b=!b)s+=b?"\\ ":" /";return s+t;}

Ungolfed

    string f(int n)
    {
        string t = "\n", s = n > 1 ? "  " + new string('_', n / 2 * 4) + t : "";
        for (var b = n < 0; n-- >= 0; t += b ? "__\\" : "/", b = !b)
            s += b ? "\\ " : " /";
        return s + t;
    }
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice, not sure how I missed this before commenting on the other answers! That overload of new String is a new one to me! You seem to have missed your t="" from the golfed version, though a better thing to do would be initialize t as "\n". You can save a couple of bytes by appending to t where you flip b, saving the "{}" on the for-loop: t+=(b=!b)?"/":"__\\". \$\endgroup\$ – VisualMelon Mar 27 '15 at 11:05
  • 1
    \$\begingroup\$ @tis you can save a couple more if you define t before s and add t to the string rather than "\n" ;) \$\endgroup\$ – VisualMelon Mar 27 '15 at 12:11
1
\$\begingroup\$

Go, 156 144

func f(n int){a,b,c:="  ","","";for i:=0;i<=n;i++{if i<n/2{a+="____"};if i%2<1{b+=" /";c+="/"}else{b+=`\ `;c+=`__\`}};print(a+"\n"+b+"\n"+c)}

Ungolfed:

func f(n int) {
    a, b, c := "  ", "", ""   // Initialize 3 accumulators
    for i := 0; i <= n; i++ { // For each required triangle
        if i < n/2 {          // Yay integer math
            a += "____"
        }
        if i%2 < 1 {          // Even, uneven, (are we drawing up or downslope?)
            b += " /"
            c += "/"
        } else {
            b += `\ `
            c += `__\`
        }
    }
    print(a + "\n" + b + "\n" + c)
}

The only real trick here (and it isn't even a good one) is using 3 accumulators so I can condense the solution down to 1 loop.

The code can be run here: http://play.golang.org/p/urEO1kIjKv

\$\endgroup\$
  • \$\begingroup\$ simply use c += `__\` instead of the if i<n{c+="_"} \$\endgroup\$ – MarcDefiant Mar 25 '15 at 8:24
  • \$\begingroup\$ @MarcDefiant Updated, thanks \$\endgroup\$ – Kristoffer Sall-Storgaard Mar 25 '15 at 10:59
1
\$\begingroup\$

><> (Fish), 215 183 156 bytes

Edit: Notepad++ was giving me 5 extra bytes due to CR, so modified count accordingly

Slightly more golfed, but it is my first fish program so far >_< The requirement to not have a blank first line for 1 triangle doubled the size of the program.

99+0{:}1=?.~~"  "oo:2,:1%-v
-1  oooo  "____"  v!?  )0:/!
" /"oa~~.?=1}:{24~/:oo
v!?)0:-1o"\"v!?)0:/!-1ooo"  /"
/v   ~o"/"oa/!
!\:0)?!;"\__"ooo1-:0)?!;"/"o1-

Can test at http://fishlanguage.com/ (Int on initial stack for length)

Explanation:

       Start with initial stack as input number
99+0   Push 18 and 0 to the top of the stack
{:}    Shift the stack to the left (wraps), copy the top value, and shift it back to the left (i.e. copy bottom of stack to the top)
1=     Check to see if the top of the stack is equal to 1, pushes 1 for true, 0 for false
?.     If top of stack is zero, skip the ., otherwise jumps to x,y coordinates on top of stack (18,0). This skips the next 8 instructions
~~     Pop the top 2 values from the stack (if they're not popped by the jump)
"  "   Push the string literal "  " onto the stack
oo     Pop the top two values of stack and output them as characters
:2,    Copy top value of stack, ad divide by 2
:1%-   Since ><> uses float division, and doesn't have >= notation, remove the decimal part (if exists)
v      Redirect pointer down
/      Redirect pointer left
:0)    Copy top of stack, and see if its greater than 0 (1 for true, 0 for false)
?!v    If top of stack is non-zero, then ! is executed, which skips the next instruction (redirect), otherwise, code is redirected
"____" Push the literal "____" to the stack
oooo   Pop the top four values of stack and output them as characters
1-     Decrement the top of the stack by 1
!/     Ignore the redirect action.
       When the loop gets to 0, it goes to next line, and gets redirected to the left.
~      Pops the top of the stack (0 counter)
42     Pushes 4 and 2 to the stack
{:}    As before, copies the bottom of the stack to the top
1=?.   Also as before, if the initial value is 1, jump to (2,4) (skipping next 4 instructions
~~     Pop 2 values from stack if these instructions haven't been skipped
ao     Push 10 onto the stack and output it as a character (LF)
"/ "oo Push the literal "/ " onto the stack and output it
://    Copies the top of the stack then redirects to the line below, which then redirects to the left
:0)    Copies top of the stack and compares if its greater than 0
?!v    If it is, redirect to next line
"\"o   Push "\" to stack, then output it as a character
1-     Decrement top value of stack
:0)?!v If loop is not greater than 0, redirect to next line
       Either mode of redirect will loop to the left, and (potentially) skip the far right redirect because of the !
ao     Push 10 to stack and output it as a character (LF)
"/"o~  Push "/" to stack, then output it as a character. Pop top value of stack (the 0 from previous loop)
v      Redirects to next line, which then redirects to the right
:0)?!; If the top of the stack is not greater than 0, terminate (;)
"\__"  Pushes "\__" to the stack
ooo    Outputs top 3 stack values as characters ("__\")
1-     Decrement top of stack by 1
:0)?!; If the top of the stack is not greater than 0, terminate (;)
"/"o   Push "/" to top of stack then output it as a character
1-     Decrement top of stack by 1
!\     Ignore the redirect
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice interpreter! Did you make that yourself? \$\endgroup\$ – Sp3000 Mar 25 '15 at 23:54
  • \$\begingroup\$ Not even slightly. :P I used it extensively to teach myself the language...and to debug. I just saw the language floating around and thought it was very interesting (also want to try Marbles). \$\endgroup\$ – Fongoid Mar 26 '15 at 14:30
1
\$\begingroup\$

perl 109 108 106

$i=<>;$t=join$/,$i-1?"  "."_"x($i/2)x4:(),$m.=(" /")[$_&1]||"\\ ",$b.=("/")[$_&1]||"__\\"for 0..$i;print$t

I think this is alright for my first golf, I used Vynce's section for the first line, with the rest of my code to get past the new line problem with 1 triangle.

Now to see if I can shorten it :)

Edit: Whitespace

Edit 2: replaced "\n" with $/

1:
 /\
/__\

4:
  ________
 /\  /\  /
/__\/__\/
\$\endgroup\$
1
\$\begingroup\$

C89, 150

r(p,q,n)int*p,*q;{n?printf(p),r(q,p,n-1):puts(p);}main(c,v)int**v;{c=atoi(v[1]);if(c>1)printf("  "),r("","____",c-1);r(" /","\\ ",c);r("/","__\\",c);}

An ungolfed version:

r(p, q, n) char *p, *q; {
    if(n > 0) {
        printf(p);
        r(q, p, n-1); /* swap p and q */
    } else {
        puts(p);
    }
}

main(c, v) char**v; {
    c = atoi(v[1]);
    if(c>1) {
        printf("  ");
        r("", "____", c - 1);
    }
    r(" /", "\\ ", c);
    r("/", "__\\", c);
}

The output:

$ seq 1 3 10 | xargs -n1 ./triangles
 /\
/__\
  ________
 /\  /\  /
/__\/__\/
  ____________
 /\  /\  /\  /\
/__\/__\/__\/__\
  ____________________
 /\  /\  /\  /\  /\  /
/__\/__\/__\/__\/__\/

The stack overflows if I enter 65535 (but not if you compile with -O3!), but theoretically it should work ;-)

edit: program now fulfills the requirement that only two lines should be outputted if 1 is passed to the program edit 2: use int* instead of char*

\$\endgroup\$
  • \$\begingroup\$ You could declare main as main(c,v)**v; if that works. \$\endgroup\$ – FUZxxl Mar 24 '15 at 22:01
  • \$\begingroup\$ I was wondering if you could save something by having c or n as a global variable, so you don't have to pass that parameter to r(). I don't think your answer complies with Note that for 1 the output is two lines long but otherwise it's three. This is required. \$\endgroup\$ – Level River St Mar 25 '15 at 0:45
  • \$\begingroup\$ @FUZxxl unfortunately this doesn't work :-( error: expected declaration specifiers before ‘*’ token main(c,v)**v;{ \$\endgroup\$ – MarcDefiant Mar 25 '15 at 7:36
  • \$\begingroup\$ @steveverrill fixed it, but I needed to lenghten the code. Couldn't find a solution with a global n or c that's shorter either. \$\endgroup\$ – MarcDefiant Mar 25 '15 at 8:13
  • \$\begingroup\$ @MarcDefiant Were you able to pass an int**? \$\endgroup\$ – FUZxxl Mar 25 '15 at 9:32
1
\$\begingroup\$

C++ stdlib, 194 bytes

string f(int n){char* p[]={"____"," /\\ ","/__\\"};int x[]={(n-n%2)*2,n*2+2-n%2,n*2+1+n%2},i,j;string s=n>1?"  ":"";for (i=n>1?0:1;i<3;s+=++i<3?"\n":"")for (j=0;j<x[i];)s+=p[i][j++%4];return s;}

Test program:

#include <string>
#include <iostream>

using namespace std;

string f(int n)
{
    char* p[]={"____"," /\\ ","/__\\"};
    int x[]={(n-n%2)*2,n*2+2-n%2,n*2+1+n%2},i,j;
    string s=n>1?"  ":"";
    for (i=n>1?0:1;i<3;s+=++i<3?"\n":"")
        for (j=0;j<x[i];)
            s+=p[i][j++%4];
    return s;
}

int main(int argc, char* argv[])
{
    cout << f(10);
    return 0;
}
\$\endgroup\$
1
\$\begingroup\$

Bash, 166 127 125 119 105 bytes

printf -v l %$[$1/2]s;(($1%2))&&r= j=$l\ ||r=/ j=$l;echo "  ${l// /____}
${j// / /\ } $r
${j// //__\\}"$r

In a function:

triangle() {
    printf -v l %$[$1/2]s;(($1%2))&&r= j=$l\ ||r=/ j=$l;echo "  ${l// /____}
${j// / /\ } $r
${j// //__\\}"$r
}

With some presentations:

for i in {1..5} 10 31;do
    paste -d\  <(
        figlet -fsmall $i |
             sed 's/^/         /;s/^ *\(.\{10\}\)$/\1  /;$d'
    ) <(triangle $i)
  done

May render (if you have figlet installed):

        _      
       / |    /\  
       | |   /__\
       |_|   
      ___      ____
     |_  )    /\  /
      / /    /__\/
     /___|   
      ____     ____
     |__ /    /\  /\  
      |_ \   /__\/__\
     |___/   
     _ _       ________
    | | |     /\  /\  /
    |_  _|   /__\/__\/
      |_|    
      ___      ________
     | __|    /\  /\  /\  
     |__ \   /__\/__\/__\
     |___/   
   _  __       ____________________
  / |/  \     /\  /\  /\  /\  /\  /
  | | () |   /__\/__\/__\/__\/__\/
  |_|\__/    
    _____      ____________________________________________________________
   |__ / |    /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  
    |_ \ |   /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\
   |___/_|   

Save 2 chars if input from variable instead of $1: 103

printf -v l %$[i/2]s;((i%2))&&r= j=$l\ ||r=/ j=$l;echo "  ${l// /____}
${j// / /\ } $r
${j// //__\\}"$r

Into the loop:

for i in {1..3} {31..34};do
    [ $i == 31 ] && figlet -fsmall ...
    paste -d\  <(
        figlet -fsmall $i |
            sed 's/^/         /;s/^ *\(.\{10\}\)$/\1   /;$d'
    ) <(
        printf -v l %$[i/2]s;((i%2))&&r= j=$l\ ||r=/ j=$l;echo "  ${l// /____}
${j// / /\ } $r
${j// //__\\}"$r
    )
  done

Will render (approx) same:

        _       
       / |     /\  
       | |    /__\
       |_|    
      ___       ____
     |_  )     /\  /
      / /     /__\/
     /___|    
      ____      ____
     |__ /     /\  /\  
      |_ \    /__\/__\
     |___/    


 _ _ _ 
(_|_|_)

    _____       ____________________________________________________________
   |__ / |     /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  
    |_ \ |    /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\
   |___/_|    
  _______       ________________________________________________________________
 |__ /_  )     /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /
  |_ \/ /     /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/
 |___/___|    
  ________      ________________________________________________________________
 |__ /__ /     /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  
  |_ \|_ \    /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\
 |___/___/    
 _____ _        ____________________________________________________________________
|__ / | |      /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /
 |_ \_  _|    /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/
|___/ |_|     
\$\endgroup\$
  • 1
    \$\begingroup\$ You should post a question about a figlet implementation codegolf! \$\endgroup\$ – sergiol Feb 15 '17 at 23:28
1
\$\begingroup\$

PowerShell, 116 95 bytes

Big thanks to Mazzy and ASCII-Only for saving 21 bytes

param($n)@("  "+"_"*4*($x=$n-shr1))[$n-eq1]
" /"+"\  /"*$x+"\"*($a=$n%2)
"/"+"__\/"*$x+"__\"*$a

Try it online!

Not allowing an empty line for n = 1 ate up like 14 10 bytes. This solution is pretty brain dead now much more clever with a minimal amount of repeated code. Banker's Rounding is still the actual devil.

\$\endgroup\$
  • \$\begingroup\$ Is an empty line not allowed??? \$\endgroup\$ – ASCII-only Jan 15 at 1:39
  • \$\begingroup\$ @ASCII-only Read the 4th bullet point from the OP. \$\endgroup\$ – Veskah Jan 15 at 1:44
  • \$\begingroup\$ damnit \$\endgroup\$ – ASCII-only Jan 15 at 1:54
  • 1
    \$\begingroup\$ @ASCII-only Breaks on x = 3 The string replace is how you bypass banker's rounding \$\endgroup\$ – Veskah Jan 15 at 2:02
  • 1
    \$\begingroup\$ @mazzy you can't generate a first line, otherwise it'd be 102 \$\endgroup\$ – ASCII-only Jan 15 at 4:54
1
\$\begingroup\$

Charcoal, 27 bytes

FEN﹪鲫P×⁴_↗⊗¬ι↓P↘²↘⊗ι↑P↗⊗ι

Try it online! Link is to verbose version of code. Explanation:

FEN﹪鲫

Generate a list of alternating bits of length n and loop over them.

P×⁴_

Draw ____ without moving the cursor.

↗⊗¬ι↓

On the first and every other triangle, draw the left / side.

P↘²

Draw the \ side without moving the cursor.

↘⊗ι↑

On the second and every other triangle, draw the left \ side again to move the cursor.

P↗⊗ι

On the second and every other triangle, draw the right / side, without moving the cursor.

\$\endgroup\$
  • 1
    \$\begingroup\$ Answers no longer have to be marked as non-competing anymore \$\endgroup\$ – Jo King Jan 12 at 14:05
0
\$\begingroup\$

C, 368 Bytes

void p(char* c){printf(c);}
int x(int s,int f){int t=0,p=s;for(int i=0;i<f;i++){if(p==1){t++;p=0;}else{p=1;}}return t;}
int main(int argc,char* argv[]){int t=atoi(argv[1]);if(t>1){p("  ");for(int i=0;i<x(0,t);i++)
{p("____");}p("\n");}for(int i=0;i<x(1,t);i++){p(" /\\ ");}if(t%2==0){p(" /");}p("\n");
for(int i=0;i<x(1,t);i++){p("/__\\");}if(t%2==0){p("/");}p("\n");}

It's more if you count the #include statements, but it compiled on gcc, albeit with warnings, without them. I know it's not the shortest by far, but I still like that I did it in C.

\$\endgroup\$
  • \$\begingroup\$ The macro #define p(c)printf(c) is shorter than your function. You can omit return types on functions (they default to int). You can also define function in C89 style like this main(c,v)char**v;{}. That is short for int main(int c, char** v){} \$\endgroup\$ – MarcDefiant Mar 30 '15 at 10:10
0
\$\begingroup\$

Perl (simple) 131 125 120

fairly straightforward first pass:

$i=<>;print join"\n",$i-1?"  "."_"x(4*int($i/2)):(),join("",map{(" /","\\ ")[$_%2]}0..$i),join"",map{("/","__\\")[$_%2]}0..$i

oh who needs explicit int?

$i=<>;print join"\n",$i-1?"  "."_"x($i/2)x4:(),join("",map{(" /","\\ ")[$_%2]}0..$i),join"",map{("/","__\\")[$_%2]}0..$i
\$\endgroup\$
0
\$\begingroup\$

Prolog, 126 bytes

A+B:-writef(A,B).
$N:-(N>1,"  %r\n"+['____',N//2];!),(0is N/\1,T='/';T='')," %r%w\n"+['/\\  ',N/2,T],"%r%w\n"+['/__\\',N/2,T].

Invoke like $3.

More readable:

triangle(N):-
    (   N > 1
    ->  writef("  %r\n", ['____', N//2])
    ;   true
    ),
    (   0 is N mod 2
    ->  T = '/'
    ;   T = ''
    ),
    writef(" %r%w\n", ['/\\  ', N/2, T]),
    writef("%r%w\n", ['/__\\', N/2, T]).

Example:

?- findall(N,between(1,10,N),NN), maplist($, NN), !.
 /\  
/__\
  ____
 /\  /
/__\/
  ____
 /\  /\  
/__\/__\
  ________
 /\  /\  /
/__\/__\/
  ________
 /\  /\  /\  
/__\/__\/__\
  ____________
 /\  /\  /\  /
/__\/__\/__\/
  ____________
 /\  /\  /\  /\  
/__\/__\/__\/__\
  ________________
 /\  /\  /\  /\  /
/__\/__\/__\/__\/
  ________________
 /\  /\  /\  /\  /\  
/__\/__\/__\/__\/__\
  ____________________
 /\  /\  /\  /\  /\  /
/__\/__\/__\/__\/__\/
NN = [1, 2, 3, 4, 5, 6, 7, 8, 9|...].
\$\endgroup\$
0
\$\begingroup\$

C#: 1 line LINQ, 198 bytes

string f(int n){return(n>1?"  ":"")+string.Join("\n",new[]{"____"," /\\ ","/__\\"}.Zip(new[]{(n-n%2)*2,n*2+2-n%2,n*2+1+n%2},(s,l)=>string.Join(s,new string[n+1]).Substring(0,l)).Where(x=>x.Any()));}
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 83 bytes

{~["  {'____'x$_/2-.5}
"x($_>2),'/\  'x$_/2~($!='/'x$_%2),"
"~'/__\\'x$_/2~$!]}o*+1

Try it online!

Anonymous code block that takes a number and returns a string.

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

C (gcc), 117 115 bytes

-2 thanks to ceilingcat.

All those parentheses suggest something less clunky is surely possible.

f(n,i,j){for(j=3-1/n;j--;puts("/"+(n%2|j>1)))for(i=0;i<n+(j<2)>>1;)printf("  %.4s"+2-j*!i++,"/__\\/\\  ____"+j*4);}

Try it online!

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

05AB1E, 37 bytes

≠iðð'_I2÷4*×J}„ /„\ ‚I>∍J'/…__\‚I>∍J»

Try it online or verify the first 10 outputs.

Explanation:

≠i            } # If the (implicit) input is NOT 1:
                #   i.e. 1 → 0 (falsey)
                #   i.e. 5 → 1 (truthy)
  ðð            #  Push two spaces "  "
    '_         '#  Push string "_"
      I         #  Push the input
       2÷       #  Integer-divide it by 2
                #   i.e. 5 → 2
         4*     #  And then multiply it by 4
                #   i.e. 2 → 8
           ×    #  Repeat the "_" that many times
                #   i.e. "_" and 8 → "________"
            J   #  Join everything on the stack together to a single string
                #   i.e. "  ________"
„ /             # Push string " /"
   „\           # Push string "\ "
     ‚          # Pair them together: [" /","\ "]
      I>        # Push the input+1
        ∍       # Extend the list to that size
                #  i.e. [" /","\ "] and 2 → [" /","\ "]
                #  i.e. [" /","\ "] and 6 → [" /","\ "," /","\ "," /","\ "]
         J      # Join the list together to a single string
                #  i.e. [" /","\ "] → " /\ "
                #  i.e. [" /","\ "," /","\ "," /","\ "] → " /\  /\  /\ "
'/             '# Push string "/"
  …__\          # Push string "__\"
      ‚         # Pair them together: ["/","__\"]
       I>       # Push the input+1
         ∍      # Extend the list to that size
                #  i.e. ["/","__\"] and 2 → ["/","__\"]
                #  i.e. ["/","__\"] and 6 → ["/","__\","/","__\","/","__\"]
          J     # Join the list together to a single string
                #  i.e. ["/","__\"] → "/__\"
                #  i.e. ["/","__\","/","__\","/","__\"] → "/__\/__\/__\"
»               # Join the entire stack with a newline delimiter
                #  i.e. " /\ " and "/__\" → " /\ \n/__\"
                #  i.e. "  ________", " /\  /\  /\ " and "/__\/__\/__\"
                #   → "  ________\n /\  /\  /\ \n/__\/__\/__\"
                # (and output the result implicitly)
\$\endgroup\$
0
\$\begingroup\$

Java 11, 122 bytes

n->(n>1?"  "+"_".repeat(n/2*4)+"\n":"")+" /\\ ".repeat(n).substring(0,++n*2)+"\n"+"/__\\".repeat(n).substring(0,n/2*4+n%2)

Try it online.

Explanation:

n->                   // Method with integer parameter and String return-type
  (n>1?               //  If the input is larger than 1:
    "  "              //   Return two spaces
    +"_".repeat(      //   Appended with "_" repeated the following amount of times:
          n/2         //    The input integer-divided by 2
             *4)      //    And then multiplied by 4
    +"\n"             //   Appended with a newline
   :                  //  Else:
    "")               //   Return nothing
  +" /\\ ".repeat(n)  //  Appended with " /\ " repeated the input amount of times
    .substring(0,     //   After which we only leave the first `x` characters, where `x` is:
      ++n             //    Increase the input by 1 first with `++n`
         *2)          //    And then multiply it by 2
                      //     i.e. For input 1, `x` becomes 4 here
                      //     i.e. For input 6, `x` becomes 14 here
  +"\n"               //  Appended with a newline
  +"/__\\".repeat(n)  //  Appended with "/__\" repeated the input amount of times
    .substring(0,     //   After which we only leave the first `y` characters, where `y` is:
      n/2             //    The input+1 integer-divided by 2
         *4           //    Then multiplied by 4
           +n%2)      //    And then the input+1 modulo-2 added
                      //     i.e. For input 1, `y` becomes 4 here
                      //     i.e. For input 6, `y` becomes 13 here
\$\endgroup\$
0
\$\begingroup\$

MathGolf, 35 bytes

½û__∞* ∞qpÿ /\ *k∞⌠<p)½ÿ/__\*k¥┬'/*

Try it online!

Explanation

The program is split into 3 parts, ½û__∞* ∞qp, ÿ /\ *k∞⌠<p, and )½ÿ/__\*k¥┬'/*. One part for each line of the output.

First part

½           Halve input to integer
 û__∞       Push "__" and double
     *      Repeat string (input//2 times)
       ∞    Push space character and double
        qp  Print the spaces first, then the underscores

Second part

ÿ /\ *      Push " /\ " and repeat it <input> times
      k∞    Push input and double it
        ⌠   Increment by two
         <p Slice the string to get the first (<input>*2 + 2) characters and print

Third part

)½              Increment input by 1 and halve it to integer
  ÿ/__\*        Repeat "/__\" that many times
        k¥┬     Check if input is divisible by 2
           '/*  Repeat "/" either zero or one times based on input
\$\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.