Let's draw the Triforce

29

2

The Triforce is a fictional artifact in The Legend of Zelda, made of three identical-looking equilateral triangles representing power, wisdom and courage. Several games in the saga include an animation when the three parts finally join together.

The purpose of this challenge is to draw a single 2D frame of such a simplified animation, with a given width for the triangles and a given spacing between the parts.

Input

The input consists of two integers: a width \$w\ge1\$ and a spacing value \$s\ge0\$.

Output

The frame has to be drawn according to the following specifications:

         /\
        /  \____________ this part is horizontally centered
       /    \
      /______\
                    \___ s empty lines
                    /
   /\          /\
  /  \        /  \______ w+1 backslashes
 /    \      /    \
/______\    /______\
                \_______ 2w underscores
        |__|
          \_____________ 2s spaces

In the above example, we have \$w=3\$ and \$s=2\$.

More examples

\$w=1\$, \$s=0\$:

   /\   
  /__\  
 /\  /\ 
/__\/__\

\$w=2\$, \$s=0\$:

     /\     
    /  \    
   /____\   
  /\    /\  
 /  \  /  \ 
/____\/____\

\$w=3\$, \$s=3\$:

          /\          
         /  \         
        /    \        
       /______\       



   /\            /\   
  /  \          /  \  
 /    \        /    \ 
/______\      /______\

\$w=4\$, \$s=1\$:

          /\          
         /  \         
        /    \        
       /      \       
      /________\      

    /\          /\    
   /  \        /  \   
  /    \      /    \  
 /      \    /      \ 
/________\  /________\

Rules

  • Trailing spaces on each line are optional.
  • Extra leading spaces on each line are not allowed.
  • You may output a single extra leading newline and/or a single extra trailing newline.
  • This is .

Arnauld

Posted 2018-08-31T11:35:48.050

Reputation: 111 334

Answers

10

Python 2, 197 194 169 167 155 144 bytes

w,s=input()
l=['']*(2*-~w+s)
for i in range(-~w):W=w-i;b='/'+'_ '[i<w]*2*i+'\\';l[i::w-~s]=' '*(w+s-~W)+b,' '*W+b+'  '*(W+s)+b
print'\n'.join(l)

Try it online!


Saved:

  • -3 bytes, thanks to Mr. Xcoder

TFeld

Posted 2018-08-31T11:35:48.050

Reputation: 19 246

9

Charcoal, 25 bytes

←×_N↗⊕θ‖M≔⁺⊕θNηCη±η‖BO⊗⊕θ

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

←×_N

Input w and draw w _s.

↗⊕θ

Draw w+1 /s.

‖M

Reflect to complete the first triangle.

≔⁺⊕θNη

Input s and calculate the offset between the left and middle triangles.

Cη±η

Copy the left triangle to the middle.

‖BO⊗⊕θ

Reflect around the middle triangle to complete the triforce.

Neil

Posted 2018-08-31T11:35:48.050

Reputation: 95 035

Uh, check your math on this. This may be 25 characters, but it's 50 to 65 bytes (depending on whether you use UTF-16 or UTF-8 representation, respectively). – Stuart P. Bentley – 2018-09-03T21:45:11.210

My bad; apparently, Charcoal and Canvas have their own character mappings, which seems a touch silly to me (if you're going to use arbitrary symbols, why not use an existing selection), but whatever.

– Stuart P. Bentley – 2018-09-03T21:58:02.163

@StuartP.Bentley The point of this site is to golf program size. Many languages (there are many, many more than just Canvas & Charcoal) opted for utilizing all 8 bits per byte, since that's a very good way to reach closer to maximum golfiness. The pretty unicode is just for making code easier to read and write (you try programming in C by writing bytecode; we are humans too) – dzaima – 2018-09-03T22:14:25.820

8

Python 2, 127 124 bytes

w,s=input()
n=2*-~w+s
while n:n-=1;I=w-n+(n>w)*(w-~s);print' '*n+('  '*(n+s)).join(['/'+I*2*' _'[I>=w]+'\\'][I>w:]*-~(n<=w))

Try it online!

ovs

Posted 2018-08-31T11:35:48.050

Reputation: 21 408

7

Canvas, 20 19 16 bytes

+├:⁸╵\L_×;∔║ω╋║↕

Try it here!

Explanation:

+├                s + w + 2
  :               duplicated (for both X & Y)
   ⁸╵\            w+1 sized diagonal
      L_×         "_"*width of the diagonal
         ;∔       prepended before the diagonal
           ║      palindromize that
            ω     and push the argument of ║ (aka the unpalindromized version)
             ╋    overlap the upside down half-triangle over the upside down triangle at (s+w+2; s+w+2)
              ║   and palindromize the whole thing
               ↕  reverse everything vertically

note: in the making of this I fixed a mistake in the code, Without that fix, this would be 18 bytes.

dzaima

Posted 2018-08-31T11:35:48.050

Reputation: 19 048

Like Neil's answer, this may be 16 characters, but in Unicode terms, it's either 32 or 44 bytes, depending on which UTF you use. (I considered that it might be representable in a legacy single-byte character set like code page 437, but there's no ω or ⁸ available there, so it seems to me you'd have to go with a Unicode transformation format.)

– Stuart P. Bentley – 2018-09-03T21:53:21.333

@StuartP.Bentley Canvas uses a custom codepage, as linked in the title of my post. The github wiki for Charcoal contains its codepage too. It's agreed upon on PPCG that it's okay to answer with unicode formatted answers if there's a codepage/converter backing it up. – dzaima – 2018-09-03T21:54:46.210

Tcsh, okay (though at the point that you're using arbitrary converters, it seems to me that you might as well be writing in a language with full names and measuring a compiled VM bytecode instruction length). – Stuart P. Bentley – 2018-09-03T22:00:35.863

@StuartP.Bentley Check the Charcoal answers link - it contains human readable code! (so yes, 2 transpilations :p) People here do answer in assembly scoring as machine code, so there's no reason to answer in VMs too – dzaima – 2018-09-03T22:03:47.590

7

R, 225, 224, 214, 211, 208 bytes

function(w,s){M=matrix
C=cbind
h=w+1
k=C(apply(m<-diag(h)*60,1,rev)/4,m)
k[row(k)==h&!k]=63
z=rbind(C(a<-M(0,h,h+s),k,a),M(0,s,h*4+2*s),C(k,M(0,h,2*s),k))
z[]=intToUtf8(z+32,T)
apply(z,1,cat,sep='','
')
rm()}

Try it online!

  • -1 byte thanks to Giuseppe
  • -10 bytes after change of approach
  • -3 bytes exploting ASCII code
  • -3 bytes thanks to JayCe

digEmAll

Posted 2018-08-31T11:35:48.050

Reputation: 4 599

Since I couldn't find anything to add to this... I just renamed variables and also I am suggesting another avenue to return silently... which I am not completely satisfied with TBH. Will keep searching! TIO

– JayCe – 2018-09-02T01:01:06.320

oh wait ... if(F)0 is acceptable for sure and saves one byte. Or even better rm() for 3 bytes. – JayCe – 2018-09-02T01:03:50.237

My suggestion to use q() in my first comment is invalid as per this meta

– JayCe – 2018-09-02T01:50:26.427

@JayCe: great trick using rm() ! – digEmAll – 2018-09-02T08:04:52.963

4

Python 2, 256 248 240 228 199 195 bytes

A longer program, but slightly different approach:

f,b,o='/\ '
O=o*2
w,s=input()
l=f+'__'*w+b
a=l+O*s+l
m=n=[]
p=lambda g:(len(a)-len(g))/2*o+g
for i in range(w):m=m+[p(f+O*i+b)];t=f+O*i+b;n+=p(t+O*(w-i+s)+t),
print'\n'.join(m+[p(l)]+[o]*s+n+[a])

Try it online!


saved a lot of bytes thanks to ignoring the trailing whitespace, and incorporating some tricks from @ovs
saved even more by defining a variable earlier

micsthepick

Posted 2018-08-31T11:35:48.050

Reputation: 421

I shall have to fix this tomorrow (it works, but I can do better) – micsthepick – 2018-08-31T13:20:06.673

218 bytes. – Jonathan Frech – 2018-08-31T18:10:47.000

216 bytes – ovs – 2018-08-31T19:25:42.970

fixed byte count. – mbomb007 – 2018-09-01T03:20:18.417

that was a byproduct from when there was two – micsthepick – 2018-09-01T08:03:23.800

go ahead and edit, on mobile right now – micsthepick – 2018-09-01T08:05:32.847

that would be nice – micsthepick – 2018-09-01T08:06:55.230

4

Pascal (FPC), 296 264 bytes

const A='/';B='\';var w,s,i:word;u:string;begin read(w,s);u:=StringOfChar('_',2*w);for i:=1to w do writeln(A:w+3+s+w-i,B:i*2-1);writeln(A:w+2+s,u,B);for i:=1to s do writeln;for i:=1to w do writeln(A:w+2-i,B:i*2-1,A:2*(s+w-i)+3,B:i*2-1);write(A,u,B,A:2*s+1,u,B)end.

Try it online!

AlexRacer

Posted 2018-08-31T11:35:48.050

Reputation: 979

3

Ruby, 126 bytes

->w,s{(-v=w+1).upto(v){|i|j= ~-i%-~v;$><<[$/*s,$/+' '*(v+s)+t="/#{(j<w ?' ':?_)*j*2}\\".center(w*2+2)+' '*s*2,$/+t*2][0<=>i]}}

Try it online!

Level River St

Posted 2018-08-31T11:35:48.050

Reputation: 22 049

2

Retina 0.8.2, 141 bytes

\d+
$* 
(?=( *),( *))
¶$1/$`$`\$1$2$2$1/$`$`\
T` `\_`/ *\\(?=.*,)
s`¶(.*),( *)
$1¶$.2$*¶$1
\G(( *)/(  |__)*\\)\2(  )*\1 *¶
$2 $#3$* $#4$* $1¶

Try it online! Note: Some trailing whitespace in output. Explanation:

\d+
$* 

Convert the inputs into spaces. (The second line ends with a space.)

(?=( *),( *))
¶$1/$`$`\$1$2$2$1/$`$`\

Create the sides of the bottom two triangles with the appropriate spacing.

T` `\_`/ *\\(?=.*,)

Fill in the base of the triangles.

s`¶(.*),( *)
$1¶$.2$*¶$1

Duplicate the triangles with the appropriate vertical spacing.

\G(( *)/(  |__)*\\)\2(  )*\1 *¶
$2 $#3$* $#4$* $1¶

Convert the upper triangles into a single centred triangle.

Neil

Posted 2018-08-31T11:35:48.050

Reputation: 95 035

2

C (gcc), 404 389 bytes

#define p(x)putchar(x);
#define F for
W;S;i;a=32;b=47;c=92;f(w,s){W=w,S=s;F(;w;--w){F(i=W+w+s+1;i--;)p(a)p(b)F(i=w*2;i++-2*W;)p(a)p(c)p(10)}F(i=W+s+1;i--;)p(a)p(b)F(i=0;i++-2*W;)p(95)p(c)F(;s--+1;)p(10)F(w=W;w;--w){F(i=w;i--;)p(a)p(b)F(i=w*2;i++-2*W;)p(a)p(c)F(i=w*2+S*2;i--;)p(a)p(b)F(i=w*2;i++-2*W;)p(a)p(c)p(10)}p(b)F(i=0;i++-2*W;)p(95)p(c)F(i=S*2;i--;)p(a)p(b)F(i=0;i++-2*W;)p(95)p(c)}

Try it online!

-14 bytes from Rodolvertice

-1 byte by fixing a loop variable decrementation

crossed out 404 is almost still 404

Ungolfed:

#define p(x)putchar(x); // save 7 bytes per putchar call (+24, -182)
#define F for // save 2 bytes per for loop (+14, -28)
int W, S, i; // W is w backup, S is s backup, i is an counter variable;
int a = ' '; // save 1 byte per space printed (+5, -8) (use a instead of 32)
int b = '/'; // save 1 byte per slash printed (+5, -6) (use b instead of 47)
int c = '\\'; // save 1 byte per backslash printed (+5, -6) (use c instead of 92)
// This isn't worth it for '\n' (-5, +3) (10), or '_' (-5, +3) (95)
int f(int w, int s) {
    W = w; // Backup w and s, as we will modify them later, 
    S = s; // but will need their original values
    for(; w != 0; --w) { // Top triangle (not the bottom line)
        for(i = W+w+s+1; i != 0; --i) // leading spaces
            putchar(' ');
        putchar('/'); // left side of triangle
        for(i = 2*w; i != 2*W; ++i) // inner spaces
            putchar(' ');
        putchar('\\'); // right side of triangle
        putchar('\n'); // newline
    }
    for(i = W+s+1; i != 0; --i)
        putchar(' '); // leading spaces for the bottom line
    putchar('/'); // left side
    for(i = 0; i != 2*W; ++i)
        putchar('_'); // the bottom line
    putchar('\\'); // right side
    for(; s-- + 1 != 0;)
        putchar('\n'); // newline after the bottom line and S empty lines
    for(w = W; w != 0; --w) { // Bottom triangles
        for(i = w; i != 0; --i)
            putchar(' '); // leading spaces
        putchar('/'); // left of left triangle
        for(i = w*2; i != 2*W; ++i)
            putchar(' '); // inside of left triangle
        putchar('\\'); // right of left triangle
        for(i = w*2+S*2; i != 0; --i)
            putchar(' '); // spaces between left and right triangles
        putchar('/');
        for(i = w*2; i != 2*W; ++i)
            putchar(' '); // inside of right triangle
        putchar('\\'); // right of right triangle
        putchar('\n'); // newline
    }
    putchar('//'); // left of left
    for(i = 0; i != 2*W; ++i)
        putchar('_'); // bottom of left triangle
    putchar('\\'); // right of left
    for(i = S*2; i != 0; --i)
        putchar(' '); // space between triangles
    putchar('/'); // left of right
    for(i = 0; i != 2*W; ++i)
        putchar('_'); // bottom of left triangle
    putchar('\\'); // right of right
}


pizzapants184

Posted 2018-08-31T11:35:48.050

Reputation: 3 174

1#define f for saves a few bytes – rodolphito – 2018-09-01T19:56:07.553

Can you not do #define p putchar? – RK. – 2018-09-01T23:34:07.833

1@RK. If I did, then I would have to use p(x); instead of p(x), for (+26, -6) = +20 bytes. The semicolon is included when the macro is expanded. – pizzapants184 – 2018-09-01T23:37:45.600

284 bytes – ceilingcat – 2019-08-16T06:40:38.057

1

Jelly, 51 bytes

+‘⁶ẋ;Ɱ®Y
‘⁼þ`a”/o"”_o⁶Ṛ;ṚØ^yƊ$€©ż`j€Ḥ⁶ẋƊ}Y,@çj‘⁷ẋƊ}

Try it online!

Erik the Outgolfer

Posted 2018-08-31T11:35:48.050

Reputation: 38 134