48
\$\begingroup\$

The Sierpinsky Triangle is a fractal created by taking a triangle, decreasing the height and width by 1/2, creating 3 copies of the resulting triangle, and place them such each triangle touches the other two on a corner. This process is repeated over and over again with the resulting triangles to produce the Sierpinski triangle, as illustrated below.

enter image description here

Write a program to generate a Sierpinski triangle. You can use any method you want to generate the pattern, either by drawing the actual triangles, or by using a random algorithm to generate the picture. You can draw in pixels, ascii art, or whatever you want, so long as the output looks similar to the last picture shown above. Fewest characters wins.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ See also the old Stack Overflow version: stackoverflow.com/questions/1726698/… \$\endgroup\$ Commented Jun 9, 2012 at 3:12
  • 3
    \$\begingroup\$ I got the idea for this after seeing the pascal's triangle question, and remembering the example program for this in my TI-86 manual. I decided to convert it to QBasic and then code golf it. \$\endgroup\$ Commented Jun 9, 2012 at 3:22
  • \$\begingroup\$ There is no problem with running a challenge here that was already run on Stack Overflow, but many people will not want to present the same material again. So I link them for the edification of later visitors. \$\endgroup\$ Commented Jun 9, 2012 at 3:23
  • \$\begingroup\$ To avoid duplication, perhaps you should change to rules to allow only graphical implementations. \$\endgroup\$ Commented Jun 9, 2012 at 3:45
  • \$\begingroup\$ Lots of ideas from wolfram: wolframscience.com/nksonline/page-931 \$\endgroup\$ Commented Feb 6, 2014 at 6:06

47 Answers 47

43
\$\begingroup\$

HTML + JavaScript, 150 characters (see notes for 126 characters)

Whitespace inserted for readability and not counted.

<title></title><canvas></canvas><script> for(x=k=128;x--;)for(y=k;y--;) x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1) </script> 

The core of it is applying the rule of coloring pixels for which x & y == 0 by the conditional x&y||, which produces a “Sierpinski right triangle”; and x-~y/2,k-y are a coordinate transformation to produce the approximately equilateral display.

enter image description here

A less correct (HTML-wise) version is 126 characters:

<canvas><script> for(x=k=128;x--;)for(y=k;y--;) x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1) </script> 

(The way in which this is less correct is that it omits the title element and the end tag of the canvas element, both of which are required for a correct document even though omitting them does not change the interpretation of the document.)

Three characters can be saved by eliminating k in favor of the constant 64, at the cost of a smaller result; I wouldn't count the 8 option as it has insufficient detail.

Note that a size of 256 or higher requires attributes on the <canvas> to increase the canvas size from the default.

\$\endgroup\$
5
  • 23
    \$\begingroup\$ Nobody cares if your HTML validates at codegolf :-) Some improvements: <canvas id=c> and then c.getContext. Shorten loops: for(x=k=128;x--;)for(y=k;y--;) \$\endgroup\$ Commented Jun 9, 2012 at 15:47
  • 4
    \$\begingroup\$ ids being turned into global variables is a horrible misfeature which I refuse to acknowledge, and WebKit does not implement it in standards mode. Thank you for the loop trick. \$\endgroup\$ Commented Jun 9, 2012 at 16:53
  • 1
    \$\begingroup\$ Minor improvement: x&y?0: can be replaced with x&y|| Otherwise nice solution. \$\endgroup\$ Commented Jun 10, 2012 at 11:20
  • 5
    \$\begingroup\$ Bravo, this is just wonderful. \$\endgroup\$ Commented Jun 14, 2012 at 7:17
  • 2
    \$\begingroup\$ As this contains a script, I'd recommend titling it as HTML + Javascript. That'll make it clearer to someone skimming what sort of answer it is. \$\endgroup\$ Commented Nov 23, 2016 at 21:31
30
\$\begingroup\$

Mathematica - 32 characters

Nest[Subsuperscript[#,#,#]&,0,5] 

enter image description here

Mathematica - 37 characters

Grid@CellularAutomaton[90,{{1},0},31] 

This will produce a 2D table of 0 and 1, where 1s are drawing Sierpinski Triangle.

enter image description here

\$\endgroup\$
9
  • 2
    \$\begingroup\$ At the cost of 5 additional characters, your second solution will display better with ArrayPlot@CellularAutomaton[90, {{1}, 0}, 31] or MatrixPlot@CellularAutomaton[90, {{1}, 0}, 31]. \$\endgroup\$ Commented Jan 2, 2013 at 18:25
  • 1
    \$\begingroup\$ ...or with ReliefPlot@... \$\endgroup\$ Commented Jan 2, 2013 at 18:29
  • \$\begingroup\$ I get this. How did you get the output without all the brackets? \$\endgroup\$ Commented Mar 27, 2013 at 5:52
  • \$\begingroup\$ @Mr.Wizard hmm... where in the world brackets are from? It even works here: mathics.net Try and let me know. \$\endgroup\$ Commented Mar 27, 2013 at 6:23
  • 1
    \$\begingroup\$ @Vitaliy Kaurov The primary (32 character) solution is astonishing. Can you do the "fractal tree" challenge (elsewhere on PCG) using the same technique? \$\endgroup\$ Commented Jan 21, 2014 at 16:57
27
\$\begingroup\$

GolfScript (43 42 chars)

' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n* 

Output:

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

Change the "3" to a larger number for a larger triangle.

\$\endgroup\$
27
\$\begingroup\$

Python (234)

Maximal golfing, tiny image:

#!/usr/bin/env python3 from cairo import* s=SVGSurface('_',97,84) g=Context(s) g.scale(97,84) def f(w,x,y): v=w/2 if w>.1:f(v,x,y);f(v,x+w/4,y-v);f(v,x+v,y) else:g.move_to(x,y);g.line_to(x+v,y-w);g.line_to(x+w,y);g.fill() f(1,0,1) s.write_to_png('s.png') 

Requires python3-cairo.

To get a nice large image I needed 239 characters.

Sierpinski Triangle

\$\endgroup\$
2
  • 1
    \$\begingroup\$ import cairo as c whould save you a few characters \$\endgroup\$ Commented Jun 17, 2012 at 13:33
  • 1
    \$\begingroup\$ this answer needs more upvotes \$\endgroup\$ Commented Jan 1, 2013 at 23:47
25
\$\begingroup\$

Python, 101 86

Uses the rule 90 automaton.

x=' '*31 x+='.'+x exec"print x;x=''.join(' .'[x[i-1]!=x[i-62]]for i in range(63));"*32 

This is longer, but prettier.

x=' '*31 x+=u'Δ'+x exec u"print x;x=''.join(u' Δ'[x[i-1]!=x[i-62]]for i in range(63));"*32 

Edit: playing with strings directly, got rid of obnoxiously long slicing, made output prettier.

Output:

 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ 
\$\endgroup\$
2
  • \$\begingroup\$ That looks really cool :D \$\endgroup\$ Commented Jun 11, 2012 at 5:14
  • \$\begingroup\$ Using that U+0394 capital Delta is a really nice touch. \$\endgroup\$ Commented May 26, 2017 at 19:08
19
\$\begingroup\$

J

,/.(,~,.~)^:6,'o' 

Not ideal, since the triangle is lopsided and followed by a lot of whitespace - but interesting nonetheless I thought.

Output:

o oo o o oooo o o oo oo o o o o oooooooo o o oo oo o o o o oooo oooo o o o o oo oo oo oo o o o o o o o o oooooooooooooooo o o oo oo o o o o oooo oooo o o o o oo oo oo oo o o o o o o o o oooooooo oooooooo o o o o oo oo oo oo o o o o o o o o oooo oooo oooo oooo o o o o o o o o oo oo oo oo oo oo oo oo o o o o o o o o o o o o o o o o oooooooooooooooooooooooooooooooo o o oo oo o o o o oooo oooo o o o o oo oo oo oo o o o o o o o o oooooooo oooooooo o o o o oo oo oo oo o o o o o o o o oooo oooo oooo oooo o o o o o o o o oo oo oo oo oo oo oo oo o o o o o o o o o o o o o o o o oooooooooooooooo oooooooooooooooo o o o o oo oo oo oo o o o o o o o o oooo oooo oooo oooo o o o o o o o o oo oo oo oo oo oo oo oo o o o o o o o o o o o o o o o o oooooooo oooooooo oooooooo oooooooo o o o o o o o o oo oo oo oo oo oo oo oo o o o o o o o o o o o o o o o o oooo oooo oooo oooo oooo oooo oooo oooo o o o o o o o o o o o o o o o o oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 

A quick explanation:

The verb (,~,.~) is what's doing the work here. It's a hook which first stitches ,. the argument to itself (o -> oo) and then appends the original argument to the output:

oo 

becomes

oo o 

This verb is repeated 6 times ^:6 with the output of each iteration becoming the input of the next iteration. So

oo o 

becomes

oooo o o oo o 

which in turn becomes

oooooooo o o o o oo oo o o oooo o o oo o 

etc. I've then used the oblique adverb on append ,/. to read the rows diagonally to straighten(ish) the triangle. I didn't need to do this, as randomra points out. I could have just reversed |. the lot to get the same result. Even better, I could have just used (,,.~)^:6,'o' to save the reverse step completely.

Ah well, you live and learn. :-)

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Could you briefly explain how it works? I'm not familiar with J \$\endgroup\$ Commented Feb 27, 2013 at 10:18
  • 1
    \$\begingroup\$ |.(,~,.~)^:6,'o' is shorter and without extra spaces. And (,~,.~)^:6,1 also gives decent input in just 12 characters! \$\endgroup\$ Commented Feb 27, 2013 at 10:19
  • \$\begingroup\$ @aditsu I've added an explanation. \$\endgroup\$ Commented Feb 27, 2013 at 12:20
  • \$\begingroup\$ So if I get it, that operator concatenates two 2d arrays? \$\endgroup\$ Commented Mar 23, 2013 at 10:56
15
\$\begingroup\$

8086 Machine code - 30 bytes.

NOTE: This is not my code and should not be accepted as an answer. I found this while working on a different CG problem to emulate an 8086 CPU. The included text file credits David Stafford, but that's the best I could come up with.

I'm posting this because it's clever, short, and I thought you'd want to see it.

It makes use of overlapping opcodes to pack more instructions in a smaller space. Amazingly clever. Here is the machine code:

B0 13 CD 10 B3 03 BE A0 A0 8E DE B9 8B 0C 32 28 88 AC C2 FE 4E 75 F5 CD 16 87 C3 CD 10 C3 

A straight-up decode looks like this:

0100: B0 13 mov AL, 13h 0102: CD 10 int 10h 0104: B3 03 mov BL, 3h 0106: BE A0 A0 mov SI, A0A0h 0109: 8E DE mov DS, SI 010B: B9 8B 0C mov CX, C8Bh 010E: 32 28 xor CH, [BX+SI] 0110: 88 AC C2 FE mov [SI+FEC2h], CH 0114: 4E dec SI 0115: 75 F5 jne/jnz -11 

When run, when the jump at 0x0115 happens, notice it jumps back to 0x010C, right into the middle of a previous instruction:

0100: B0 13 mov AL, 13h 0102: CD 10 int 10h 0104: B3 03 mov BL, 3h 0106: BE A0 A0 mov SI, A0A0h 0109: 8E DE mov DS, SI 010B: B9 8B 0C mov CX, C8Bh 010E: 32 28 xor CH, [BX+SI] 0110: 88 AC C2 FE mov [SI+FEC2h], CH 0114: 4E dec SI 0115: 75 F5 jne/jnz -11 010C: 8B 0C mov CX, [SI] 010E: 32 28 xor CH, [BX+SI] 0110: 88 AC C2 FE mov [SI+FEC2h], CH 0114: 4E dec SI 0115: 75 F5 jne/jnz -11 010C: 8B 0C mov CX, [SI] 

Brilliant! Hope you guys don't mind me sharing this. I know it's not an answer per se, but it's of interest to the challenge.

Here it is in action:

Running

\$\endgroup\$
15
\$\begingroup\$

80x86 Code / MsDos - 10 Bytes

As a sizecoder specialized for very tiny intros on MsDos i managed to come up with a program that occupies only 10 bytes.

in hex:

04 13 CD 10 20 E9 B4 0C E2 F6 

enter image description here

in asm:

X: add al,0x13 int 0x10 and cl,ch mov ah,0x0C loop X 

The first version i coded was "Colpinski" which is 16 bytes in size, and even interactive in a way that you can change the color with the keyboard and the mouse. Together with "Frag" - another sizecoder - we brought that one down to 13 bytes, allowing for a 10 byte program which just contains the core routine.

It gets a bit more interesting when things are animated, so i'll mention another version, Zoompinski 64 - trying to mimic the exact behavior of "Zoompinski C64" in 512 bytes - also for MsDos, 64 bytes in size as the name suggests.

It's possible to optimize this further downto 31 Bytes, while losing elegance, colors and symmetry (source and executable available behind the link above)

Download the original and comment on "Pouet"

\$\endgroup\$
1
  • 2
    \$\begingroup\$ You should post a hex dump of your code, so we can see the actual bytes. \$\endgroup\$ Commented Oct 6, 2016 at 19:44
14
\$\begingroup\$

QBasic 151 Characters

As an example, here is how it can be done in QBasic.

SCREEN 9 H=.5 P=300 FOR I=1 TO 9^6 N=RND IF N > 2/3 THEN X=H+X*H:Y=Y*H ELSEIF N > 1/3 THEN X=H^2+X*H:Y=H+Y*H ELSE X=X*H:Y=Y*H END IF PSET(P-X*P,P-Y*P) NEXT 

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ Could you describe the measure under which this program is 129 characters? I get 151 if I strip out all the probably-unnecessary whitespace. (I'm not familiar with QBasic.) \$\endgroup\$ Commented Jun 9, 2012 at 12:44
  • \$\begingroup\$ I stripped out all the whitespace for my count. I guess I could count only non-essential whitespace. I'm not sure what the "official" rule is for code golf. \$\endgroup\$ Commented Jun 10, 2012 at 0:41
  • 4
    \$\begingroup\$ You should count the actual number of characters, including whitespace, in a program which runs and produces the correct output. Naturally you'll want to have no unnecessary whitespace. \$\endgroup\$ Commented Jun 10, 2012 at 0:43
  • 1
    \$\begingroup\$ Corrected my character count. \$\endgroup\$ Commented Jun 12, 2012 at 12:18
14
\$\begingroup\$

Python (42)

I originally wanted to post a few suggestions on boothbys solution (who actually uses rule 18 :), but i didn't have enough reputation to comment, so i made it into another answer. Since he changed his approach, i added some explanation. My suggestions would have been:

  1. use '%d'*64%tuple(x) instead of ''.join(map(str,x)
  2. shift in zeros instead of wraping the list around

which would have led to the following code (93 characters):

x=[0]*63 x[31]=1 exec"print'%d'*63%tuple(x);x=[a^b for a,b in zip(x[1:]+[0],[0]+x[:-1])];"*32 

But i optimzed further, first by using a longint instead of an integer array and just printing the binary representation (75 characters):

x=2**31 exec"print'%d'*63%tuple(1&x>>i for i in range(63));x=x<<1^x>>1;"*32 

And finally by printing the octal representation, which is already supported by printf interpolation (42 characters):

x=8**31 exec"print'%063o'%x;x=x*8^x/8;"*32 

All of them will print:

000000000000000000000000000000010000000000000000000000000000000 000000000000000000000000000000101000000000000000000000000000000 000000000000000000000000000001000100000000000000000000000000000 000000000000000000000000000010101010000000000000000000000000000 000000000000000000000000000100000001000000000000000000000000000 000000000000000000000000001010000010100000000000000000000000000 000000000000000000000000010001000100010000000000000000000000000 000000000000000000000000101010101010101000000000000000000000000 000000000000000000000001000000000000000100000000000000000000000 000000000000000000000010100000000000001010000000000000000000000 000000000000000000000100010000000000010001000000000000000000000 000000000000000000001010101000000000101010100000000000000000000 000000000000000000010000000100000001000000010000000000000000000 000000000000000000101000001010000010100000101000000000000000000 000000000000000001000100010001000100010001000100000000000000000 000000000000000010101010101010101010101010101010000000000000000 000000000000000100000000000000000000000000000001000000000000000 000000000000001010000000000000000000000000000010100000000000000 000000000000010001000000000000000000000000000100010000000000000 000000000000101010100000000000000000000000001010101000000000000 000000000001000000010000000000000000000000010000000100000000000 000000000010100000101000000000000000000000101000001010000000000 000000000100010001000100000000000000000001000100010001000000000 000000001010101010101010000000000000000010101010101010100000000 000000010000000000000001000000000000000100000000000000010000000 000000101000000000000010100000000000001010000000000000101000000 000001000100000000000100010000000000010001000000000001000100000 000010101010000000001010101000000000101010100000000010101010000 000100000001000000010000000100000001000000010000000100000001000 001010000010100000101000001010000010100000101000001010000010100 010001000100010001000100010001000100010001000100010001000100010 101010101010101010101010101010101010101010101010101010101010101 

Of course there is also a graphical solution (131 characters):

from PIL.Image import* from struct import* a='' x=2**31 exec"a+=pack('>Q',x);x=x*2^x/2;"*32 fromstring('1',(64,32),a).save('s.png') 

very small sierpinsky triangle :D

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 36: x=8**31;exec"print'%o'%x;x^=x/8;"*32 \$\endgroup\$ Commented Feb 27, 2013 at 11:08
13
\$\begingroup\$

APL (51)

 A←67⍴0⋄A[34]←1⋄' ○'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A] 

Explanation:

  • A←67⍴0: A is a vector of 67 zeroes
  • A[34]←1: the 34th element is 1
  • {...}A: starting with A, do:
  • ~⊃⍵:: if the first element of the current row is zero
  • ⍵,∇: add the current row to the answer, and recurse with:
  • (1⌽⍵)≠¯1⌽⍵: the vector where each element is the XOR of its neighbours in the previous generation
  • ⋄⍬: otherwise, we're done
  • 32 67⍴: format this in a 67x32 matrix
  • 1+: add one to select the right value from the character array
  • ' ○'[...]: output either a space (not part of the triangle) or a circle (when it is part of the triangle)

Output:

 ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ 
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Yikes. I expected this to be 4 characters, using binomials mod 2... (ok... maybe a little longer than that) \$\endgroup\$ Commented Jun 9, 2012 at 17:47
13
\$\begingroup\$

Haskell (291)

I'm not very good at golfing haskell codes.

solve n = tri (putStrLn "") [2^n] n tri m xs 1 = do putStrLn (l1 1 xs "/\\" 0) putStrLn (l1 1 xs "/__\\" 1) m tri m xs n=tri m' xs (n-1) where m'=tri m (concat[[x-o,x+o]|x<-xs]) (n-1) o=2^(n-1) l1 o [] s t="" l1 o (x:xs) s t=replicate (x-o-t) ' '++s++l1 (x+2+t) xs s t 

Output of solve 4 is:

 /\ /__\ /\ /\ /__\/__\ /\ /\ /__\ /__\ /\ /\ /\ /\ /__\/__\/__\/__\ /\ /\ /__\ /__\ /\ /\ /\ /\ /__\/__\ /__\/__\ /\ /\ /\ /\ /__\ /__\ /__\ /__\ /\ /\ /\ /\ /\ /\ /\ /\ /__\/__\/__\/__\/__\/__\/__\/__\ 
\$\endgroup\$
0
11
\$\begingroup\$

C 127 119 116 108 65

This one uses the trick of the HTML answer of ^ i & j getting it to print pretty output would take 1 more char (you can get really ugly output by sacrificing the a^).

a=32,j;main(i){for(;++i<a;)putchar(a^i&j);++j<a&&main(puts(""));} 

To make it pretty turn (32^i&j) to (32|!(i&j)) and turn it from ++i<a to ++i<=a. However wasting chars on looks seems ungolfish to me.

Ugly output:

 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! "" "" "" "" "" "" "" "" "# !"# !"# !"# !"# !"# !"# !"# $$$$ $$$$ $$$$ $$$$ !$%$% ! !$%$% ! !$%$% ! !$%$% ""$$&& ""$$&& ""$$&& ""$$&& "#$%&' !"#$%&' !"#$%&' !"#$%&' (((((((( (((((((( ! ! !()()()() ! ! ! !()()()() "" ""((**((** "" ""((**((** "# !"#()*+()*+ !"# !"#()*+()*+ $$$$((((,,,, $$$$((((,,,, !$%$%()(),-,- ! !$%$%()(),-,- ""$$&&((**,,.. ""$$&&((**,,.. "#$%&'()*+,-./ !"#$%&'()*+,-./ 0000000000000000 ! ! ! ! ! ! !0101010101010101 "" "" "" ""0022002200220022 "# !"# !"# !"#0123012301230123 $$$$ $$$$0000444400004444 !$%$% ! !$%$%0101454501014545 ""$$&& ""$$&&0022446600224466 "#$%&' !"#$%&'0123456701234567 ((((((((0000000088888888 ! ! !()()()()0101010189898989 "" ""((**((**0022002288::88:: "# !"#()*+()*+0123012389:;89:; $$$$((((,,,,000044448888<<<< !$%$%()(),-,-010145458989<=<= ""$$&&((**,,..0022446688::<<>> "#$%&'()*+,-./0123456789:;<=>? 

I actually kind of like how it looks. But if you insist on it being pretty you can dock four chars. Pretty Output:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !! !! !! !! !! !! !! ! ! ! ! ! ! ! ! ! !! !!!! !!!! !!!! ! ! ! ! ! ! ! ! ! !! !! !! ! ! ! ! ! !!!!!! !!!!!!!! ! ! ! ! ! ! ! ! ! !! !! !! ! ! ! ! ! !! !!!! ! ! ! ! ! !! ! ! ! !!!!!!!!!!!!!! ! ! ! ! ! ! ! ! ! !! !! !! ! ! ! ! ! !! !!!! ! ! ! ! ! !! ! ! ! !!!!!! ! ! ! ! ! !! ! ! ! !! ! ! ! ! ! 

Leaving up the older 108 char, cellular automata version.

j,d[99][99];main(i){d[0][31]=3;for(;i<64;)d[j+1][i]=putchar(32|d[j][i+2]^d[j][i++]);++j<32&&main(puts(""));} 

So I don't think I'm going to get it much shorter than this so I'll explain the code. I'll leave this explanation up, as some of the tricks could be useful.

j,d[99][99]; // these init as 0 main(i){ //starts at 1 (argc) d[0][48]=3; //seed the automata (3 gives us # instead of !) for(;i<98;) // print a row d[j+1][i]=putchar(32|d[j][i+2]]^d[j][i++]); //relies on undefined behavoir. Works on ubuntu with gcc ix864 //does the automata rule. 32 + (bitwise or can serve as + if you know //that (a|b)==(a^b)), putchar returns the char it prints ++j<32&&main(puts("")); // repeat 32 times // puts("") prints a newline and returns 1, which is nice } 

Some output

 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
\$\endgroup\$
4
  • 1
    \$\begingroup\$ This does not appear to be a Sierpinski triangle; it splits into three sub-triangles (proceeding downward) rather than two, and it can be seen that this produces no large central empty triangle. \$\endgroup\$ Commented Jun 9, 2012 at 13:10
  • 1
    \$\begingroup\$ That's because I used the wrong rule :O. Fixed, and shaved a couple of chars. \$\endgroup\$ Commented Jun 9, 2012 at 13:59
  • \$\begingroup\$ Suggest for(31[*d]=3; instead of d[0][31]=3;for(; \$\endgroup\$ Commented Mar 6, 2021 at 9:28
  • \$\begingroup\$ Shaved off 1 byte. 64 bytes \$\endgroup\$ Commented Apr 22 at 7:19
10
\$\begingroup\$

PostScript, 120 chars

-7 -4 moveto 14 0 rlineto 7{true upath dup 2{120 rotate uappend}repeat[2 0 0 2 7 4]concat}repeat matrix setmatrix stroke 

Ghostscript output:

Rendered Ghostscript output

This is drawing the figure by recursively tripling what's already drawn.

First step is drawing a line. The line is saved as a userpath, then the userpath is added two more times after rotating 120 degrees each time. [2 0 0 2 7 4]concat moves the "rotation point" to the center of the next big white "center triangle" that is to be enclosed by replications of the triangle we already have. Here, we're back to step 1 (creating a upath that's tripled by rotation).

The number of iterations is controlled by the first number in line 3.

\$\endgroup\$
3
  • \$\begingroup\$ +1 Very nice. I had no idea upath could be used like that. \$\endgroup\$ Commented Jul 20, 2012 at 6:28
  • \$\begingroup\$ Hey, you've got the rep to add that image now! \$\endgroup\$ Commented Jan 1, 2013 at 7:01
  • \$\begingroup\$ @luserdroog: That's right (even partly thanks to you)! \$\endgroup\$ Commented Jan 1, 2013 at 15:21
7
\$\begingroup\$

J (9 characters)

Easily the ugliest, you really need to squint to see the output ;)

2|!/~i.32 

produces the output

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 

of course you can display it graphically:

load 'viewmat' viewmat 2|!/~i.32 

Image

\$\endgroup\$
2
  • \$\begingroup\$ how the... what? \$\endgroup\$ Commented Apr 3, 2013 at 17:16
  • 4
    \$\begingroup\$ The code exploits the property of Pascal's triangle that if you colour all the odd (even) numbers black (white), you end up with the Sierpinski triangle. (see this image). i.32 generates the list 0 1 2 ... 31. Then !/~ computes the binomial coefficients of each element in the list against itself, i.e. produces a 32 x 32 matrix which has Pascal's triangle embedded in it. Then 2| is simply each element in this matrix mod 2, producing Sierpinski's triangle. \$\endgroup\$ Commented Apr 7, 2013 at 17:55
5
\$\begingroup\$

Python (75)

I'm two years late to the party, but I'm surprised that nobody has taken this approach yet

from pylab import* x=[[1,1],[1,0]] for i in'123':x=kron(x,x) imsave('a',x) 

level7

Uses the Kronecker product to replace a matrix by multiple copies of itself.

I could save two chars by using x=kron(x,x);x=kron(x,x) in line three to get a 16x16 pixel image with three visible levels or add another char to the iterator and end up with a 2^16 x 2^16 = 4.3 Gigapixel image and 15 triangle levels.

\$\endgroup\$
5
\$\begingroup\$

8086 Machine code - 18 bytes (unknown author) / 27 bytes (mine)

In early 1990s, I organized a small competition on programmer's board on a Croatian BBS, who can write the smallest program to draw the Sierpinski triangle.

My best solution was 27 bytes long, but there were several even smaller and unique solutions, with smallest one being only 18 bytes of machine code. Unfortunately, I forgot the name of the person who wrote it - so if the original author is reading this, please contact me. :)


18 bytes solution by an unknown Croatian programmer:

Bytes: B0 13 CD 10 B5 A0 8E D9 30 84 3F 01 AC 32 04 E2 F7 C3 0100 B013 MOV AL,13 0102 CD10 INT 10 0104 B5A0 MOV CH,A0 0106 8ED9 MOV DS,CX 0108 30843F01 XOR [SI+013F],AL 010C AC LODSB 010D 3204 XOR AL,[SI] 010F E2F7 LOOP 0108 0111 C3 RET 

Which draws this:

Sierpinski triangle in 18 bytes of 8086 machine code


My 27 bytes solution:

Bytes: B0 13 CD 10 B7 A0 8E C3 8E DB BF A0 00 AA B9 C0 9E BE 61 FF AC 32 04 AA E2 FA C3 0100 B013 MOV AL,13 0102 CD10 INT 10 0104 B7A0 MOV BH,A0 0106 8EC3 MOV ES,BX 0108 8EDB MOV DS,BX 010A BFA000 MOV DI,00A0 010D AA STOSB 010E B9C09E MOV CX,9EC0 0111 BE61FF MOV SI,FF61 0114 AC LODSB 0115 3204 XOR AL,[SI] 0117 AA STOSB 0118 E2FA LOOP 0114 011A C3 RET 

Which draws this:

Sierpinski triangle in 27 bytes of 8086 machine code

\$\endgroup\$
4
\$\begingroup\$

APL, 37 32 (28 23)

Upright triangle (37 32-char)

({((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 2⍴'/\' 

Explanation

  • 1 2⍴'/\': Create a 1×2 character matrix /\
  • {((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}: A function that pad the right argument on both sides with blanks to create a matrix double as wide, then laminates the right argument itself doubled onto the bottom.
    E.g. /\ would become
 /\ /\/\
  • ⍣⎕: Recur the function (user input) times.

Example output

 /\ /\/\ /\ /\ /\/\/\/\ /\ /\ /\/\ /\/\ /\ /\ /\ /\ /\/\/\/\/\/\/\/\ /\ /\ /\/\ /\/\ /\ /\ /\ /\ /\/\/\/\ /\/\/\/\ /\ /\ /\ /\ /\/\ /\/\ /\/\ /\/\ /\ /\ /\ /\ /\ /\ /\ /\ /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ 

Skewed Triangle (28 23-char)

({(⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 1⍴'○' 

Explaination

  • 1 1⍴'○': Create a 1×1 character matrix
  • {(⍵,∊⍵)⍪⍵,⍵}: A function that pad the right argument on the right with blanks to create a matrix double as wide, then laminates the right argument itself doubled onto the bottom.
    E.g. would become
○ ○○
  • ⍣⎕: Recur the function (user input) times.

Example output

○ ○○ ○ ○ ○○○○ ○ ○ ○○ ○○ ○ ○ ○ ○ ○○○○○○○○ ○ ○ ○○ ○○ ○ ○ ○ ○ ○○○○ ○○○○ ○ ○ ○ ○ ○○ ○○ ○○ ○○ ○ ○ ○ ○ ○ ○ ○ ○ ○○○○○○○○○○○○○○○○ 
\$\endgroup\$
4
\$\begingroup\$

matlab 56

v=[1;-1;j];plot(filter(1,[1,-.5],v(randi(3,1,1e4))),'.') 

enter image description here

\$\endgroup\$
4
\$\begingroup\$

6502 ASM, 134 bytes

start: lda #$e1 sta $0 lda #$01 sta $1 ldy #$20 w_e: ldx #$00 eor ($0, x) sta ($0),y inc $0 bne w_e inc $1 ldx $1 cpx #$06 bne w_e rts 

Pretty simple. Displays the triangles. Note that the top and left sides of the image are invisible due to the white background of PPCG.

sierpinski

\$\endgroup\$
4
\$\begingroup\$

Mathematica 63

ListPlot@ReIm@NestList[#/2+RandomChoice[{0,1,-1}^(1/3)]&,0.,8!] 

enter image description here

Mathematica 67

Region@Polygon@ReIm@Nest[Tr/@Tuples[{p,#}/2]&,{p={0,1,-1}^(1/3)},6] 

enter image description here

\$\endgroup\$
4
\$\begingroup\$

Binary Lambda Calculus (BLC): 51 bits (6.375 bytes)

000100011010000100000101010110110000010110110011010 

Equivalent to the term \(\(0 0) \(\\(0 1 \\0 1 1) (0 0))).

Since BLC has no graphical output, this solution assumes a screen as defined in this blog post.

The term has no normal form and generates an infinitely detailed Sierpinski triangle. Rendered using lambda-screen which stops after a finite amount of reductions:

resulting image, slightly rotated sierpinski triangle

\$\endgroup\$
4
\$\begingroup\$

Python (190 bytes)

from turtle import* def l():left(60) def r():right(60) def f():forward(1) def L(n): if n:n-=1;R(n);l();L(n);l();R(n) else:f() def R(n): if n:n-=1;L(n);r();R(n);r();L(n) else:f() l();L(8) 

Try it online

Draw fractal line filling Sierpinsky Triangle

\$\endgroup\$
1
  • \$\begingroup\$ Before running, I recommend inserting ht();speed(0);up();goto(20-window_width()/2, 20-window_height()/2);down() after the import. This will run it much faster and ensure that the output fits on the canvas. \$\endgroup\$ Commented Oct 6, 2016 at 19:42
3
\$\begingroup\$

Logo, 75 characters

59 characters for just the first function, the second one calls the first with the size and the depth/number of iterations. So you could just call the first function from the interpreter with the command: e 99 5, or whatever size you want to output

to e :s :l if :l>0[repeat 3[e :s/2 :l-1 fd :s rt 120]] end to f e 99 5 end 
\$\endgroup\$
2
  • \$\begingroup\$ +1 I've read about Logo. What interpreter are you using? ... Logo might be a natural fit for my l-system challenge. \$\endgroup\$ Commented Feb 28, 2013 at 2:50
  • \$\begingroup\$ If you just remove the to f and end around e 99 5, you have a complete runnable program in fewer characters. Also, in UCBLogo (though not other versions) you can lose the colons on the variables to save more chars. \$\endgroup\$ Commented Jan 21, 2014 at 3:38
3
\$\begingroup\$

J (18 characters)

' *'{~(,,.~)^:9 ,1 

Result

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

Applesoft BASIC, 246 bytes

1 HGR:HCOLOR=3:HOME:DIM x(3),y(3):x(0)=0:y(0)=160:x(1)=90:y(1)=0:x(2)=180:y(2)=160:FOR i=0 to 2:HPLOT x(i),y(i):NEXT i 2 x=int(RND(1)*180):y=int(RND(1)*150):HPLOT x,y:FOR i=1 to 2000:v=int(rnd(1)*3):x=(x+x(v))/2:y=(y+y(v))/2:HPLOT x,y:NEXT:GOTO 2 

Not the most efficient, nor does it draw a perfect Sierpinski, but it's fun. May stick pixels in random places or miss a few points depending on your system's pRNG quality.

output

Ungolfed:

100 HGR : HCOLOR=3 : HOME 110 REM set up three points to form a triangle 120 DIM x(3), y(3) 130 x(0) = 0 : y(0) = 160 140 x(1) = 90 : y(1) = 0 150 x(2) = 180 : y(2) = 160 160 REM plot the vertices of the triangle 170 FOR i= 0 to 2 180 HPLOT x(i), y(i) 190 NEXT i 200 REM pick a random starting point 210 x = int(RND(1)*180) : y = int(RND(1)*150) 220 hplot x,y 230 FOR i = 1 to 2000 240 REM randomly pick one of the triangle vertices 250 v = int(rnd(1)*3) 260 REM move the point half way to the triangle vertex 270 x = (x + x(v)) / 2 : y = (y + y(v)) / 2 280 HPLOT x,y 290 NEXT 
\$\endgroup\$
1
  • \$\begingroup\$ minor golfs: 225 bytes \$\endgroup\$ Commented Jan 28 at 8:11
3
\$\begingroup\$

APL (Dyalog Classic), 12 bytes

×.≥∘⍉⍨↑,⍳⎕⍴2 

Try it online!

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

Asymptote, 152 bytes

I'll add this, mostly since I've seen more or less no answers in asymptote on this site. A few wasted bytes for nice formatting and generality, but I can live with that. Changing A,B and C will change where the corners of the containing triangle are, but probably not in the way you think. Increase the number in the inequality to increase the depth.

pair A=(0,0),B=(1,0),C=(.5,1);void f(pair p,int d){if(++d<7){p*=2;f(p+A*2,d);f(p+B*2,d);f(p+C*2,d);}else{fill(shift(p/2)*(A--B--C--cycle));}}f((0,0),0); 

or ungolfed and readable

pair A=(0,0), B=(1,0), C=(.5,1); void f(pair p, int d) { if (++d<7) { p *= 2; f(p+A*2,d); f(p+B*2,d); f(p+C*2,d); } else { fill(shift(p/2)*(A--B--C--cycle)); } } f((0,0),0); 

So asymptote is a neat vector graphics language with somewhat C-like syntax. Quite useful for somewhat technical diagrams. Output is of course in a vector format by default (eps, pdf, svg) but can be converted into basically everything imagemagick supports. Output:

Sierpinski triangle

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

Mathematica, 29 bytes

Image@Array[BitAnd,{2,2}^9,0] 

Image@Array[BitAnd,{2,2}^9,0]

The Sierpinski tetrahedron can be drawn in a similar way:

Image3D[1-Array[BitXor,{2,2,2}^7,0]] 

Image3D[1-Array[BitXor,{2,2,2}^7,0]]

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

J, 37 35 bytes

-2 bytes thanks to FrownyFrog

(,.~,~' '&,.^:#)@[&0' /\',:'/__\'"_ 

Try it online!

This is Peter Taylor's ascii art version converted to J. Could save bytes with a less pretty version, but why?

 /\ /__\ /\ /\ /__\/__\ /\ /\ /__\ /__\ /\ /\ /\ /\ /__\/__\/__\/__\ 
\$\endgroup\$
4
  • \$\begingroup\$ @]^:[ -> @[&0 and ' /\ ' -> ' /\' \$\endgroup\$ Commented Apr 22, 2019 at 18:50
  • \$\begingroup\$ Do you happen to know where &0 trick is documented? \$\endgroup\$ Commented Apr 23, 2019 at 4:03
  • 1
    \$\begingroup\$ Mentioned here at the bottom of the page. While it saves a byte you lose the ability to have negative number of repeats. \$\endgroup\$ Commented Apr 23, 2019 at 11:30
  • \$\begingroup\$ Oh, you should be able to swap the operands to ,~ around. \$\endgroup\$ Commented Apr 25, 2019 at 18:29

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.