Penrose Triangle Codegolf

SVG (HTML5), 191 bytes

<svg width=498 height=433 stroke=#000><path d=M211,134l38,66L154,365H496L458,431H40 /><path fill=#777 d=M211,2L2,365l38,66L211,134l95,165h76 /><path fill=#FFF d=M496,365L287,2H211L382,299H192


Python 2, 211 201 195 188 175 173 bytes

from turtle import*
d="t(120);fd(333);rt(120);fd(67);"
s="color(0,%r);begin_fill();fd(200);l"+d+"rt(60);fd(400);r"+d+"end_fill();fd(133);rt(180);"
exec s%'#fff'+s%0+s%'gray'

Unfortunately, exec is not implemented in Trinket, so this cannot be tested online as-is. At least, not in the free version. I printed out the string and pasted as code to test it. If you're clever with scripts, you could resize the html/css as necessary to get a larger canvas. Let me know if you do.

Try it online - uses a smaller size since the site's canvas is too small for 400px, but you can see the entire output.

Ungolfed:

from turtle import*
w=200
def f(n):
  c=255*n/2
  color(0,(c,c,c))
  begin_fill()
  fd(w)
  lt(120)
  fd(5*w/3)
  rt(120)
  fd(w/3)
  rt(60)
  fd(2*w)
  rt(120)
  fd(5*w/3)
  rt(120)
  fd(w/3)
  end_fill()
  fd(2*w/3)
  rt(180)
f(2);f(0);f(1)

PHP, 153 bytes

This will only work if the short_open_tag setting is enabled. The source code contains unprintable characters, so have a hex dump instead:

0000000: 3c3f 3d67 7a69 6e66 6c61 7465 2827 b329  <?=gzinflate('.)
0000010: 2e4b 5728 cb4c 2d77 caaf b0d5 3531 3000  .KW(.L-w....510.
0000020: 611d 0b08 5628 2e29 cacf 4eb5 5536 3030  a...V(.)..N.U600
0000030: b0b3 2948 2cc9 5048 b1f5 d535 35d6 3536  ..)H,.PH...55.56
0000040: b7d0 8152 c6a6 263a 8626 c6ba 8626 0660  ...R..&:.&...&.`
0000050: dac2 5cc7 14c8 b234 0452 510a 6999 3939  ..\....4.RQ.i.99
0000060: b6ca 6969 690a 2545 8979 c569 f945 b9b6  ..iii.%E.y.i.E..
0000070: 45f9 2589 25a9 1a06 9a0a fa14 990a 7415  E.%.%.........t.
0000080: a6a9 8646 949a 9b5e 945a 8969 ae2e cc60  ...F...^.Z.i...`
0000090: 7d60 88d9 0100 2729 3b                   }`....');

The decompressed data looks like this (with line breaks added for legibility):

<svg viewBox=-400-400,800,800 stroke=#000>
<path d=M-53-378,53-378,354,143-140,143-87,50,191,50Z fill=#fff transform=rotate(0) />
<path d=M-53-378,53-378,354,143-140,143-87,50,191,50Z fill=#000 transform=rotate(120) />
<path d=M-53-378,53-378,354,143-140,143-87,50,191,50Z fill=grey transform=rotate(-120) />
</svg>

Although the SVG data isn't entirely valid, PHP serves it as text/html by default. Without a doctype declaration, the document is handled in quirks mode, which is very forgiving.

To improve the compression, I broke the image into three "7"-shaped parts that can be drawn using near-identical <path> elements. The resulting image will expand to fill the viewport. Here's a screen grab from a 500×500 pixel window:

Screen grab of 500×500 pixel Penrose triangle SVG image