Sierpinski triangle: Difference between revisions
Thundergnat (talk | contribs) m syntax highlighting fixup automation |
|||
Line 35: | Line 35: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">F sierpinski(n) |
||
V d = [String(‘*’)] |
V d = [String(‘*’)] |
||
L(i) 0 .< n |
L(i) 0 .< n |
||
Line 42: | Line 42: | ||
R d |
R d |
||
print(sierpinski(4).join("\n"))</ |
print(sierpinski(4).join("\n"))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 65: | Line 65: | ||
=={{header|8080 Assembly}}== |
=={{header|8080 Assembly}}== |
||
< |
<syntaxhighlight lang="8080asm">argmt: equ 5Dh ; Command line argument |
||
puts: equ 9 ; CP/M syscall to print a string |
puts: equ 9 ; CP/M syscall to print a string |
||
putch: equ 2 ; CP/M syscall to print a character |
putch: equ 2 ; CP/M syscall to print a character |
||
Line 125: | Line 125: | ||
pop b |
pop b |
||
ret |
ret |
||
nl: db 13,10,'$'</ |
nl: db 13,10,'$'</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 149: | Line 149: | ||
=={{header|8086 Assembly}}== |
=={{header|8086 Assembly}}== |
||
< |
<syntaxhighlight lang="asm">putch: equ 2 ; MS-DOS syscall to print character |
||
puts: equ 9 ; MS-DOS syscall to print string |
puts: equ 9 ; MS-DOS syscall to print string |
||
argmt: equ 5Dh ; MS-DOS still has FCB in same place as CP/M |
argmt: equ 5Dh ; MS-DOS still has FCB in same place as CP/M |
||
Line 190: | Line 190: | ||
jnz line |
jnz line |
||
ret |
ret |
||
nl: db 13,10,'$'</ |
nl: db 13,10,'$'</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 214: | Line 214: | ||
=={{header|ACL2}}== |
=={{header|ACL2}}== |
||
< |
<syntaxhighlight lang="lisp">(defun pascal-row (prev) |
||
(if (endp (rest prev)) |
(if (endp (rest prev)) |
||
(list 1) |
(list 1) |
||
Line 252: | Line 252: | ||
(let ((height (1- (expt 2 levels)))) |
(let ((height (1- (expt 2 levels)))) |
||
(print-odds (pascal-triangle height) |
(print-odds (pascal-triangle height) |
||
height)))</ |
height)))</syntaxhighlight> |
||
=={{header|Action!}}== |
=={{header|Action!}}== |
||
< |
<syntaxhighlight lang="action!">PROC Main() |
||
BYTE x,y,size=[16] |
BYTE x,y,size=[16] |
||
Line 280: | Line 280: | ||
FI |
FI |
||
y==-1 |
y==-1 |
||
OD</ |
OD</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Sierpinski_triangle.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Sierpinski_triangle.png Screenshot from Atari 8-bit computer] |
||
Line 304: | Line 304: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
This Ada example creates a string of the binary value for each line, converting the '0' values to spaces. |
This Ada example creates a string of the binary value for each line, converting the '0' values to spaces. |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_Io; use Ada.Text_Io; |
||
with Ada.Strings.Fixed; |
with Ada.Strings.Fixed; |
||
with Interfaces; use Interfaces; |
with Interfaces; use Interfaces; |
||
Line 356: | Line 356: | ||
Sierpinski(N); |
Sierpinski(N); |
||
end loop; |
end loop; |
||
end Sieteri_Triangles;</ |
end Sieteri_Triangles;</syntaxhighlight> |
||
alternative using modular arithmetic: |
alternative using modular arithmetic: |
||
< |
<syntaxhighlight lang="ada">with Ada.Command_Line; |
||
with Ada.Text_IO; |
with Ada.Text_IO; |
||
Line 386: | Line 386: | ||
end if; |
end if; |
||
Sierpinski (N); |
Sierpinski (N); |
||
end Main;</ |
end Main;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>XXXXXXXXXXXXXXXX |
<pre>XXXXXXXXXXXXXXXX |
||
Line 410: | Line 410: | ||
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
||
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - test missing transput}} --> |
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - test missing transput}} --> |
||
< |
<syntaxhighlight lang="algol68">PROC sierpinski = (INT n)[]STRING: ( |
||
FLEX[0]STRING d := "*"; |
FLEX[0]STRING d := "*"; |
||
FOR i TO n DO |
FOR i TO n DO |
||
Line 425: | Line 425: | ||
); |
); |
||
printf(($gl$,sierpinski(4)))</ |
printf(($gl$,sierpinski(4)))</syntaxhighlight> |
||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
{{Trans|C}} |
{{Trans|C}} |
||
< |
<syntaxhighlight lang="algolw">begin |
||
integer SIZE; |
integer SIZE; |
||
SIZE := 16; |
SIZE := 16; |
||
Line 442: | Line 442: | ||
write(); |
write(); |
||
end for_y |
end for_y |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
Line 448: | Line 448: | ||
{{Trans|Haskell}} |
{{Trans|Haskell}} |
||
Centering any previous triangle block over two adjacent duplicates: |
Centering any previous triangle block over two adjacent duplicates: |
||
< |
<syntaxhighlight lang="applescript">------------------- SIERPINKSI TRIANGLE ------------------ |
||
-- sierpinski :: Int -> [String] |
-- sierpinski :: Int -> [String] |
||
Line 550: | Line 550: | ||
on unwords(xs) |
on unwords(xs) |
||
intercalate(space, xs) |
intercalate(space, xs) |
||
end unwords</ |
end unwords</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> * |
<pre> * |
||
Line 571: | Line 571: | ||
Or generating each line as an XOR / Rule 90 / Pascal triangle rewrite of the previous line. |
Or generating each line as an XOR / Rule 90 / Pascal triangle rewrite of the previous line. |
||
{{Trans|JavaScript}} |
{{Trans|JavaScript}} |
||
< |
<syntaxhighlight lang="applescript">----------- SIERPINSKI TRIANGLE BY XOR / RULE 90 --------- |
||
-- sierpinskiTriangle :: Int -> String |
-- sierpinskiTriangle :: Int -> String |
||
Line 717: | Line 717: | ||
return lst |
return lst |
||
end tell |
end tell |
||
end zipWith</ |
end zipWith</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> * |
<pre> * |
||
Line 739: | Line 739: | ||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang="rebol">sierpinski: function [order][ |
||
s: shl 1 order |
s: shl 1 order |
||
loop (s-1)..0 'y [ |
loop (s-1)..0 'y [ |
||
Line 751: | Line 751: | ||
] |
] |
||
sierpinski 4</ |
sierpinski 4</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 773: | Line 773: | ||
=={{header|ATS}}== |
=={{header|ATS}}== |
||
<syntaxhighlight lang="ats"> |
|||
<lang ATS> |
|||
(* ****** ****** *) |
(* ****** ****** *) |
||
// |
// |
||
Line 816: | Line 816: | ||
// |
// |
||
} (* end of [main0] *) |
} (* end of [main0] *) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
ahk [http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=150 discussion] |
ahk [http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=150 discussion] |
||
< |
<syntaxhighlight lang="autohotkey">Loop 6 |
||
MsgBox % Triangle(A_Index) |
MsgBox % Triangle(A_Index) |
||
Line 838: | Line 838: | ||
Triangle(n-1,x+u,y+u) ; smaller triangle down right |
Triangle(n-1,x+u,y+u) ; smaller triangle down right |
||
Return t |
Return t |
||
}</ |
}</syntaxhighlight> |
||
=={{header|APL}}== |
=={{header|APL}}== |
||
< |
<syntaxhighlight lang="apl">A←67⍴0⋄A[34]←1⋄' #'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A]</syntaxhighlight> |
||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
< |
<syntaxhighlight lang="awk"># WST.AWK - Waclaw Sierpinski's triangle contributed by Dan Nielsen |
||
# syntax: GAWK -f WST.AWK [-v X=anychar] iterations |
# syntax: GAWK -f WST.AWK [-v X=anychar] iterations |
||
# example: GAWK -f WST.AWK -v X=* 2 |
# example: GAWK -f WST.AWK -v X=* 2 |
||
Line 868: | Line 868: | ||
} |
} |
||
exit(0) |
exit(0) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|BASH (feat. sed & tr)}}== |
=={{header|BASH (feat. sed & tr)}}== |
||
Line 876: | Line 876: | ||
other language just as well, but is particularly well suited for |
other language just as well, but is particularly well suited for |
||
tools like sed and tr. |
tools like sed and tr. |
||
< |
<syntaxhighlight lang="bash"> |
||
#!/bin/bash |
#!/bin/bash |
||
Line 900: | Line 900: | ||
rec $1 | tr 'dsx' ' *' |
rec $1 | tr 'dsx' ' *' |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
Line 907: | Line 907: | ||
<!-- {{works with|RapidQ}} doesn't work for me -- Erik Siers, 12 March 2012 --> |
<!-- {{works with|RapidQ}} doesn't work for me -- Erik Siers, 12 March 2012 --> |
||
< |
<syntaxhighlight lang="qbasic">DECLARE SUB triangle (x AS INTEGER, y AS INTEGER, length AS INTEGER, n AS INTEGER) |
||
CLS |
CLS |
||
Line 920: | Line 920: | ||
triangle x + length * 2, y + length, length / 2, n - 1 |
triangle x + length * 2, y + length, length / 2, n - 1 |
||
END IF |
END IF |
||
END SUB</ |
END SUB</syntaxhighlight> |
||
Note: The total height of the triangle is 2 * parameter ''length''. It should be power of two so that the pattern matches evenly with the character cells. Value 16 will thus create pattern of 32 lines. |
Note: The total height of the triangle is 2 * parameter ''length''. It should be power of two so that the pattern matches evenly with the character cells. Value 16 will thus create pattern of 32 lines. |
||
Line 926: | Line 926: | ||
==={{header|BASIC256}}=== |
==={{header|BASIC256}}=== |
||
<syntaxhighlight lang="basic256"> |
|||
<lang BASIC256> |
|||
clg |
clg |
||
call triangle (1, 1, 60) |
call triangle (1, 1, 60) |
||
Line 941: | Line 941: | ||
end if |
end if |
||
end subroutine |
end subroutine |
||
</syntaxhighlight> |
|||
</lang> |
|||
==={{header|BBC BASIC}}=== |
==={{header|BBC BASIC}}=== |
||
< |
<syntaxhighlight lang="bbcbasic"> MODE 8 |
||
OFF |
OFF |
||
Line 961: | Line 961: | ||
PROCsierpinski(x%+l%+l%, y%+l%, l% DIV 2) |
PROCsierpinski(x%+l%+l%, y%+l%, l% DIV 2) |
||
ENDIF |
ENDIF |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
==={{header|FreeBASIC}}=== |
==={{header|FreeBASIC}}=== |
||
< |
<syntaxhighlight lang="freebasic">sub sier(x as uinteger, y as uinteger, l as uinteger) |
||
if l=0 then |
if l=0 then |
||
locate y, x: print "*" |
locate y, x: print "*" |
||
Line 975: | Line 975: | ||
cls |
cls |
||
sier(1,1,2^3)</ |
sier(1,1,2^3)</syntaxhighlight> |
||
==={{header|IS-BASIC}}=== |
==={{header|IS-BASIC}}=== |
||
< |
<syntaxhighlight lang="is-basic">100 PROGRAM "Triangle.bas" |
||
110 TEXT 40 |
110 TEXT 40 |
||
120 CALL TRIANGLE(1,1,8) |
120 CALL TRIANGLE(1,1,8) |
||
Line 989: | Line 989: | ||
190 CALL TRIANGLE(X+2*L,Y+L,INT(L/2)) |
190 CALL TRIANGLE(X+2*L,Y+L,INT(L/2)) |
||
200 END IF |
200 END IF |
||
210 END DEF</ |
210 END DEF</syntaxhighlight> |
||
=={{header|BCPL}}== |
=={{header|BCPL}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="bcpl">get "libhdr" |
||
manifest $( SIZE = 1 << 4 $) |
manifest $( SIZE = 1 << 4 $) |
||
Line 1,004: | Line 1,004: | ||
wrch('*N') |
wrch('*N') |
||
$) |
$) |
||
$)</ |
$)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> * |
<pre> * |
||
Line 1,027: | Line 1,027: | ||
This is a version of the cellular automaton (''rule 90'') construction. The order, ''N'', is specified by the first number on the stack. It uses a single line of the playfield for the cell buffer, so the upper limit for ''N'' should be 5 on a standard Befunge-93 implementation. Interpreters with poor memory handling may not work with anything over 3, though, and a Befunge-98 interpreter should theoretically be unlimited. |
This is a version of the cellular automaton (''rule 90'') construction. The order, ''N'', is specified by the first number on the stack. It uses a single line of the playfield for the cell buffer, so the upper limit for ''N'' should be 5 on a standard Befunge-93 implementation. Interpreters with poor memory handling may not work with anything over 3, though, and a Befunge-98 interpreter should theoretically be unlimited. |
||
< |
<syntaxhighlight lang="befunge">41+2>\#*1#2-#<:#\_$:1+v |
||
v:$_:#`0#\\#00#:p#->#1< |
v:$_:#`0#\\#00#:p#->#1< |
||
>2/1\0p:2/\::>1-:>#v_1v |
>2/1\0p:2/\::>1-:>#v_1v |
||
Line 1,033: | Line 1,033: | ||
vg11<\*g11!:g 0-1:::<p< |
vg11<\*g11!:g 0-1:::<p< |
||
>!*+!!\0g11p\ 0p1-:#^_v |
>!*+!!\0g11p\ 0p1-:#^_v |
||
@$$_\#!:#::#-^#1\$,+55<</ |
@$$_\#!:#::#-^#1\$,+55<</syntaxhighlight> |
||
=={{header|Burlesque}}== |
=={{header|Burlesque}}== |
||
< |
<syntaxhighlight lang="burlesque">{JPp{ |
||
-.'sgve! |
-.'sgve! |
||
J{JL[2./+.' j.*PppP.+PPj.+}m[ |
J{JL[2./+.' j.*PppP.+PPj.+}m[ |
||
Line 1,043: | Line 1,043: | ||
.+ |
.+ |
||
}{vv{"*"}}PPie} 's sv |
}{vv{"*"}}PPie} 's sv |
||
4 'sgve!unsh</ |
4 'sgve!unsh</syntaxhighlight> |
||
=={{header|BQN}}== |
=={{header|BQN}}== |
||
< |
<syntaxhighlight lang="bqn">Sierp ← {" •" ⊏˜ (⌽↕2⋆𝕩)⌽˘∾˘∾⟜0¨∧´∘∨⌜˜⥊↕2⥊˜𝕩}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,064: | Line 1,064: | ||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#define SIZE (1 << 4) |
#define SIZE (1 << 4) |
||
Line 1,076: | Line 1,076: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
===Automaton=== |
===Automaton=== |
||
This solution uses a cellular automaton (''rule 90'') with a proper initial status. |
This solution uses a cellular automaton (''rule 90'') with a proper initial status. |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <stdbool.h> |
#include <stdbool.h> |
||
Line 1,114: | Line 1,114: | ||
} |
} |
||
free(cp); |
free(cp); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="c">void sierpinski_triangle(int n) |
||
{ |
{ |
||
int i; |
int i; |
||
Line 1,133: | Line 1,133: | ||
free(b); |
free(b); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="c">int main() |
||
{ |
{ |
||
sierpinski_triangle(4); |
sierpinski_triangle(4); |
||
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections; |
using System.Collections; |
||
Line 1,180: | Line 1,180: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="csharp">namespace RosettaCode { |
||
class Program { |
class Program { |
||
static void Main(string[] args) { |
static void Main(string[] args) { |
||
Line 1,189: | Line 1,189: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{trans|C}} |
{{trans|C}} |
||
{{works with|C sharp|C#|6.0+}} |
{{works with|C sharp|C#|6.0+}} |
||
< |
<syntaxhighlight lang="csharp">using static System.Console; |
||
class Sierpinsky |
class Sierpinsky |
||
{ |
{ |
||
Line 1,208: | Line 1,208: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{trans|OCaml}} |
{{trans|OCaml}} |
||
{{works with|C sharp|C#|3.0+}} |
{{works with|C sharp|C#|3.0+}} |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
using System.Linq; |
using System.Linq; |
||
Line 1,238: | Line 1,238: | ||
Console.WriteLine(s); |
Console.WriteLine(s); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Or, with fold / reduce (a.k.a. aggregate): |
Or, with fold / reduce (a.k.a. aggregate): |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
using System.Linq; |
using System.Linq; |
||
Line 1,267: | Line 1,267: | ||
foreach(string s in Sierpinski(4)) { Console.WriteLine(s); } |
foreach(string s in Sierpinski(4)) { Console.WriteLine(s); } |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{works with|C++11}} |
{{works with|C++11}} |
||
A STL-centric recursive solution that uses the new lambda functions in C++11. |
A STL-centric recursive solution that uses the new lambda functions in C++11. |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <string> |
#include <string> |
||
#include <list> |
#include <list> |
||
Line 1,306: | Line 1,306: | ||
sierpinski(4, ostream_iterator<string>(cout, "\n")); |
sierpinski(4, ostream_iterator<string>(cout, "\n")); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Line 1,312: | Line 1,312: | ||
{{trans|Common Lisp}} |
{{trans|Common Lisp}} |
||
With a touch of Clojure's sequence handling. |
With a touch of Clojure's sequence handling. |
||
< |
<syntaxhighlight lang="clojure">(ns example |
||
(:require [clojure.contrib.math :as math])) |
(:require [clojure.contrib.math :as math])) |
||
Line 1,337: | Line 1,337: | ||
(bit-xor (bit-shift-left v 1) (bit-shift-right v 1)))))) |
(bit-xor (bit-shift-left v 1) (bit-shift-right v 1)))))) |
||
(sierpinski-triangle 4)</ |
(sierpinski-triangle 4)</syntaxhighlight> |
||
=={{header|CLU}}== |
=={{header|CLU}}== |
||
{{trans|Fortran}} |
{{trans|Fortran}} |
||
< |
<syntaxhighlight lang="clu">sierpinski = proc (size: int) returns (string) |
||
ss: stream := stream$create_output() |
ss: stream := stream$create_output() |
||
Line 1,367: | Line 1,367: | ||
sierpinski(4) |
sierpinski(4) |
||
) |
) |
||
end start_up</ |
end start_up</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> * |
<pre> * |
||
Line 1,388: | Line 1,388: | ||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
{{trans|Fortran}} and retains a more Fortran-like coding style than is really idiomatic in COBOL. |
{{trans|Fortran}} and retains a more Fortran-like coding style than is really idiomatic in COBOL. |
||
< |
<syntaxhighlight lang="cobol">identification division. |
||
program-id. sierpinski-triangle-program. |
program-id. sierpinski-triangle-program. |
||
data division. |
data division. |
||
Line 1,423: | Line 1,423: | ||
if r is equal to zero then display ' * ' with no advancing. |
if r is equal to zero then display ' * ' with no advancing. |
||
if r is not equal to zero then display ' ' with no advancing. |
if r is not equal to zero then display ' ' with no advancing. |
||
compute c = c * (i - k) / (k + 1).</ |
compute c = c * (i - k) / (k + 1).</syntaxhighlight> |
||
=={{header|Comal}}== |
=={{header|Comal}}== |
||
< |
<syntaxhighlight lang="comal">0010 DIM part$(FALSE:TRUE) OF 2 |
||
0020 part$(FALSE):=" ";part$(TRUE):="* " |
0020 part$(FALSE):=" ";part$(TRUE):="* " |
||
0030 INPUT "Order? ":order# |
0030 INPUT "Order? ":order# |
||
Line 1,435: | Line 1,435: | ||
0080 PRINT |
0080 PRINT |
||
0090 ENDFOR y# |
0090 ENDFOR y# |
||
0100 END</ |
0100 END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Order? 4 |
<pre>Order? 4 |
||
Line 1,456: | Line 1,456: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">(defun print-sierpinski (order) |
||
(loop with size = (expt 2 order) |
(loop with size = (expt 2 order) |
||
repeat size |
repeat size |
||
Line 1,462: | Line 1,462: | ||
do (fresh-line) |
do (fresh-line) |
||
(loop for i below (integer-length v) |
(loop for i below (integer-length v) |
||
do (princ (if (logbitp i v) "*" " ")))))</ |
do (princ (if (logbitp i v) "*" " ")))))</syntaxhighlight> |
||
Printing each row could also be done by printing the integer in base 2 and replacing zeroes with spaces: <tt>(princ (substitute #\Space #\0 (format nil "~%~2,vR" (1- (* 2 size)) v)))</tt> |
Printing each row could also be done by printing the integer in base 2 and replacing zeroes with spaces: <tt>(princ (substitute #\Space #\0 (format nil "~%~2,vR" (1- (* 2 size)) v)))</tt> |
||
Line 1,470: | Line 1,470: | ||
Alternate approach: |
Alternate approach: |
||
< |
<syntaxhighlight lang="lisp">(defun sierpinski (n) |
||
(if (= n 0) '("*") |
(if (= n 0) '("*") |
||
(nconc (mapcar (lambda (e) (format nil "~A~A~0@*~A" (make-string (expt 2 (1- n)) :initial-element #\ ) e)) (sierpinski (1- n))) |
(nconc (mapcar (lambda (e) (format nil "~A~A~0@*~A" (make-string (expt 2 (1- n)) :initial-element #\ ) e)) (sierpinski (1- n))) |
||
(mapcar (lambda (e) (format nil "~A ~A" e e)) (sierpinski (1- n)))))) |
(mapcar (lambda (e) (format nil "~A ~A" e e)) (sierpinski (1- n)))))) |
||
(mapc #'print (sierpinski 4))</ |
(mapc #'print (sierpinski 4))</syntaxhighlight> |
||
=={{header|Cowgol}}== |
=={{header|Cowgol}}== |
||
< |
<syntaxhighlight lang="cowgol">include "cowgol.coh"; |
||
include "argv.coh"; |
include "argv.coh"; |
||
Line 1,518: | Line 1,518: | ||
print_nl(); |
print_nl(); |
||
y := y - 1; |
y := y - 1; |
||
end loop;</ |
end loop;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,541: | Line 1,541: | ||
=={{header|D}}== |
=={{header|D}}== |
||
===Run-time Version=== |
===Run-time Version=== |
||
< |
<syntaxhighlight lang="d">void main() /*@safe*/ { |
||
import std.stdio, std.algorithm, std.string, std.array; |
import std.stdio, std.algorithm, std.string, std.array; |
||
Line 1,552: | Line 1,552: | ||
} |
} |
||
d.join('\n').writeln; |
d.join('\n').writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> * |
<pre> * |
||
Line 1,573: | Line 1,573: | ||
===Compile-time Version=== |
===Compile-time Version=== |
||
Same output. |
Same output. |
||
< |
<syntaxhighlight lang="d">import std.string, std.range, std.algorithm; |
||
string sierpinski(int level) pure nothrow /*@safe*/ { |
string sierpinski(int level) pure nothrow /*@safe*/ { |
||
Line 1,586: | Line 1,586: | ||
pragma(msg, 4.sierpinski); |
pragma(msg, 4.sierpinski); |
||
void main() {}</ |
void main() {}</syntaxhighlight> |
||
===Simple Version=== |
===Simple Version=== |
||
{{trans|C}} |
{{trans|C}} |
||
Same output. |
Same output. |
||
< |
<syntaxhighlight lang="d">void showSierpinskiTriangle(in uint order) nothrow @safe @nogc { |
||
import core.stdc.stdio: putchar; |
import core.stdc.stdio: putchar; |
||
Line 1,607: | Line 1,607: | ||
void main() nothrow @safe @nogc { |
void main() nothrow @safe @nogc { |
||
4.showSierpinskiTriangle; |
4.showSierpinskiTriangle; |
||
}</ |
}</syntaxhighlight> |
||
===Alternative Version=== |
===Alternative Version=== |
||
This uses a different algorithm and shows a different output. |
This uses a different algorithm and shows a different output. |
||
< |
<syntaxhighlight lang="d">import core.stdc.stdio: putchar; |
||
import std.algorithm: swap; |
import std.algorithm: swap; |
||
Line 1,652: | Line 1,652: | ||
'\n'.putchar; |
'\n'.putchar; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> # |
<pre> # |
||
Line 1,723: | Line 1,723: | ||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
{{trans|DWScript}} |
{{trans|DWScript}} |
||
< |
<syntaxhighlight lang="delphi">program SierpinskiTriangle; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 1,748: | Line 1,748: | ||
begin |
begin |
||
PrintSierpinski(4); |
PrintSierpinski(4); |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|Draco}}== |
=={{header|Draco}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="draco">word SIZE = 1 << 4; |
||
proc nonrec main() void: |
proc nonrec main() void: |
||
Line 1,763: | Line 1,763: | ||
writeln() |
writeln() |
||
od |
od |
||
corp</ |
corp</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> * |
<pre> * |
||
Line 1,784: | Line 1,784: | ||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
{{trans|E}} |
{{trans|E}} |
||
< |
<syntaxhighlight lang="delphi">procedure PrintSierpinski(order : Integer); |
||
var |
var |
||
x, y, size : Integer; |
x, y, size : Integer; |
||
Line 1,801: | Line 1,801: | ||
PrintSierpinski(4); |
PrintSierpinski(4); |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">def printSierpinski(order, out) { |
||
def size := 2**order |
def size := 2**order |
||
for y in (0..!size).descending() { |
for y in (0..!size).descending() { |
||
Line 1,813: | Line 1,813: | ||
out.println() |
out.println() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<lang |
<syntaxhighlight lang="e">? printSierpinski(4, stdout)</syntaxhighlight> |
||
Non-ASCII version (quality of results will depend greatly on text renderer): |
Non-ASCII version (quality of results will depend greatly on text renderer): |
||
< |
<syntaxhighlight lang="e">def printSierpinski(order, out) { |
||
def size := 2**order |
def size := 2**order |
||
for y in (0..!size).descending() { |
for y in (0..!size).descending() { |
||
Line 1,827: | Line 1,827: | ||
out.println() |
out.println() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Erlang}} |
{{trans|Erlang}} |
||
< |
<syntaxhighlight lang="elixir">defmodule RC do |
||
def sierpinski_triangle(n) do |
def sierpinski_triangle(n) do |
||
f = fn(x) -> IO.puts "#{x}" end |
f = fn(x) -> IO.puts "#{x}" end |
||
Line 1,844: | Line 1,844: | ||
end |
end |
||
RC.sierpinski_triangle(4)</ |
RC.sierpinski_triangle(4)</syntaxhighlight> |
||
=={{header|Elm}}== |
=={{header|Elm}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
< |
<syntaxhighlight lang="elm">import String exposing (..) |
||
import Html exposing (..) |
import Html exposing (..) |
||
import Html.Attributes as A exposing (..) |
import Html.Attributes as A exposing (..) |
||
Line 1,899: | Line 1,899: | ||
, ("font-size", "1em") |
, ("font-size", "1em") |
||
, ("text-align", "left") |
, ("text-align", "left") |
||
]</ |
]</syntaxhighlight> |
||
Link to live demo: http://dc25.github.io/sierpinskiElm/ |
Link to live demo: http://dc25.github.io/sierpinskiElm/ |
||
Line 1,905: | Line 1,905: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
{{trans|OCaml}} |
{{trans|OCaml}} |
||
< |
<syntaxhighlight lang="erlang">-module(sierpinski). |
||
-export([triangle/1]). |
-export([triangle/1]). |
||
Line 1,915: | Line 1,915: | ||
triangle(N, Down, Sp) -> |
triangle(N, Down, Sp) -> |
||
NewDown = [Sp++X++Sp || X<-Down]++[X++" "++X || X <- Down], |
NewDown = [Sp++X++Sp || X<-Down]++[X++" "++X || X <- Down], |
||
triangle(N-1, NewDown, Sp++Sp).</ |
triangle(N-1, NewDown, Sp++Sp).</syntaxhighlight> |
||
=={{header|Euphoria}}== |
=={{header|Euphoria}}== |
||
{{trans|BASIC}} |
{{trans|BASIC}} |
||
< |
<syntaxhighlight lang="euphoria">procedure triangle(integer x, integer y, integer len, integer n) |
||
if n = 0 then |
if n = 0 then |
||
position(y,x) puts(1,'*') |
position(y,x) puts(1,'*') |
||
Line 1,930: | Line 1,930: | ||
clear_screen() |
clear_screen() |
||
triangle(1,1,8,4)</ |
triangle(1,1,8,4)</syntaxhighlight> |
||
=={{header|Excel}}== |
=={{header|Excel}}== |
||
Line 1,942: | Line 1,942: | ||
{{Works with|Office 365 betas 2021}} |
{{Works with|Office 365 betas 2021}} |
||
< |
<syntaxhighlight lang="lisp">sierpinskiTriangle |
||
=LAMBDA(c, |
=LAMBDA(c, |
||
LAMBDA(n, |
LAMBDA(n, |
||
Line 1,986: | Line 1,986: | ||
) |
) |
||
)(grid) |
)(grid) |
||
)</ |
)</syntaxhighlight> |
||
and also assuming the following generic bindings in the Name Manager for the WorkBook: |
and also assuming the following generic bindings in the Name Manager for the WorkBook: |
||
< |
<syntaxhighlight lang="lisp">APPENDCOLS |
||
=LAMBDA(xs, |
=LAMBDA(xs, |
||
LAMBDA(ys, |
LAMBDA(ys, |
||
Line 2,048: | Line 2,048: | ||
) |
) |
||
) |
) |
||
)</ |
)</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 2,494: | Line 2,494: | ||
=={{header|F Sharp|F#}}== |
=={{header|F Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp">let sierpinski n = |
||
let rec loop down space n = |
let rec loop down space n = |
||
if n = 0 then |
if n = 0 then |
||
Line 2,506: | Line 2,506: | ||
let () = |
let () = |
||
List.iter (fun (i:string) -> System.Console.WriteLine(i)) (sierpinski 4)</ |
List.iter (fun (i:string) -> System.Console.WriteLine(i)) (sierpinski 4)</syntaxhighlight> |
||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
{{trans|OCaml}} |
{{trans|OCaml}} |
||
< |
<syntaxhighlight lang="factor">USING: io kernel math sequences ; |
||
IN: sierpinski |
IN: sierpinski |
||
Line 2,526: | Line 2,526: | ||
: sierpinski ( n -- ) |
: sierpinski ( n -- ) |
||
[ { "*" } " " ] dip (sierpinski) print ;</ |
[ { "*" } " " ] dip (sierpinski) print ;</syntaxhighlight> |
||
=={{header|FALSE}}== |
=={{header|FALSE}}== |
||
{{incorrect|FALSE|Different results with different interpreters (like http://morphett.info/false/false.html and http://www.quirkster.com/iano/js/false-js.html}} |
{{incorrect|FALSE|Different results with different interpreters (like http://morphett.info/false/false.html and http://www.quirkster.com/iano/js/false-js.html}} |
||
< |
<syntaxhighlight lang="false">[[$][$1&["*"]?$~1&[" "]?2/]#%" |
||
"]s: { stars } |
"]s: { stars } |
||
[$@$@|@@&~&]x: { xor } |
[$@$@|@@&~&]x: { xor } |
||
[1\[$][1-\2*\]#%]e: { 2^n } |
[1\[$][1-\2*\]#%]e: { 2^n } |
||
[e;!1\[$][\$s;!$2*x;!\1-]#%%]t: |
[e;!1\[$][\$s;!$2*x;!\1-]#%%]t: |
||
4t;!</ |
4t;!</syntaxhighlight> |
||
=={{header|FOCAL}}== |
=={{header|FOCAL}}== |
||
< |
<syntaxhighlight lang="focal">01.10 A "ORDER",O;S S=2^(O+1) |
||
01.20 F X=0,S;S L(X)=0 |
01.20 F X=0,S;S L(X)=0 |
||
01.30 S L(S/2)=1 |
01.30 S L(S/2)=1 |
||
Line 2,551: | Line 2,551: | ||
03.10 F X=0,S;S K(X)=FABS(L(X-1)-L(X+1)) |
03.10 F X=0,S;S K(X)=FABS(L(X-1)-L(X+1)) |
||
03.20 F X=0,S;S L(X)=K(X)</ |
03.20 F X=0,S;S L(X)=K(X)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,574: | Line 2,574: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
< |
<syntaxhighlight lang="forth">: stars ( mask -- ) |
||
begin |
begin |
||
dup 1 and if [char] * else bl then emit |
dup 1 and if [char] * else bl then emit |
||
Line 2,587: | Line 2,587: | ||
loop 2drop ; |
loop 2drop ; |
||
5 triangle</ |
5 triangle</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
This method calculates a Pascal's triangle and replaces every odd number with a * and every even number with a space. The limitation of this approach is the size of the numbers in the Pascal's triangle. Tryng to print an order 8 Sierpinski's triangle will overflow a 32 bit integer and an order 16 will overflow a 64 bit integer. |
This method calculates a Pascal's triangle and replaces every odd number with a * and every even number with a space. The limitation of this approach is the size of the numbers in the Pascal's triangle. Tryng to print an order 8 Sierpinski's triangle will overflow a 32 bit integer and an order 16 will overflow a 64 bit integer. |
||
< |
<syntaxhighlight lang="fortran">program Sierpinski_triangle |
||
implicit none |
implicit none |
||
Line 2,620: | Line 2,620: | ||
end do |
end do |
||
end subroutine Triangle |
end subroutine Triangle |
||
end program Sierpinski_triangle</ |
end program Sierpinski_triangle</syntaxhighlight> |
||
=={{header|GAP}}== |
=={{header|GAP}}== |
||
< |
<syntaxhighlight lang="gap"># Using parity of binomial coefficients |
||
SierpinskiTriangle := function(n) |
SierpinskiTriangle := function(n) |
||
local i, j, s, b; |
local i, j, s, b; |
||
Line 2,660: | Line 2,660: | ||
* * * * * * * * |
* * * * * * * * |
||
* * * * * * * * |
* * * * * * * * |
||
* * * * * * * * * * * * * * * * </ |
* * * * * * * * * * * * * * * * </syntaxhighlight> |
||
=={{header|gnuplot}}== |
=={{header|gnuplot}}== |
||
Making and printing a text string, using bit-twiddling to decide whether each character should be a space or a star. |
Making and printing a text string, using bit-twiddling to decide whether each character should be a space or a star. |
||
< |
<syntaxhighlight lang="gnuplot"># Return a string space or star to print at x,y. |
||
# Must have x<y. x<0 is the left side of the triangle. |
# Must have x<y. x<0 is the left side of the triangle. |
||
# If x<-y then it's before the left edge and the return is a space. |
# If x<-y then it's before the left edge and the return is a space. |
||
Line 2,680: | Line 2,680: | ||
# Print rows 0 to 15, which is the order 4 triangle per the task. |
# Print rows 0 to 15, which is the order 4 triangle per the task. |
||
print triangle(0,15)</ |
print triangle(0,15)</syntaxhighlight> |
||
=={{header|Go}}== |
=={{header|Go}}== |
||
"Δ" (Greek capital letter delta) looks good for grain, as does Unicode triangle, "△". ASCII "." and "^" are pleasing. "/\\", "´`", and "◢◣"" make interesting wide triangles. |
"Δ" (Greek capital letter delta) looks good for grain, as does Unicode triangle, "△". ASCII "." and "^" are pleasing. "/\\", "´`", and "◢◣"" make interesting wide triangles. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 2,709: | Line 2,709: | ||
fmt.Println(r) |
fmt.Println(r) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Golfscript}}== |
=={{header|Golfscript}}== |
||
Cambia el "3" a un número mayor para un triángulo más grande. |
Cambia el "3" a un número mayor para un triángulo más grande. |
||
< |
<syntaxhighlight lang="golfscript">' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n*</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,736: | Line 2,736: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Solution: |
Solution: |
||
< |
<syntaxhighlight lang="groovy">def stPoints; |
||
stPoints = { order, base=[0,0] -> |
stPoints = { order, base=[0,0] -> |
||
def right = [base[0], base[1]+2**order] |
def right = [base[0], base[1]+2**order] |
||
Line 2,751: | Line 2,751: | ||
stPoints(order).each { grid[it[0]][it[1]] = (order%10).toString() } |
stPoints(order).each { grid[it[0]][it[1]] = (order%10).toString() } |
||
grid |
grid |
||
}</ |
}</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="groovy">stGrid(0).reverse().each { println it.sum() } |
||
println() |
println() |
||
stGrid(1).reverse().each { println it.sum() } |
stGrid(1).reverse().each { println it.sum() } |
||
Line 2,766: | Line 2,766: | ||
stGrid(5).reverse().each { println it.sum() } |
stGrid(5).reverse().each { println it.sum() } |
||
println() |
println() |
||
stGrid(6).reverse().each { println it.sum() }</ |
stGrid(6).reverse().each { println it.sum() }</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,906: | Line 2,906: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">sierpinski 0 = ["*"] |
||
sierpinski n = map ((space ++) . (++ space)) down ++ |
sierpinski n = map ((space ++) . (++ space)) down ++ |
||
map (unwords . replicate 2) down |
map (unwords . replicate 2) down |
||
Line 2,912: | Line 2,912: | ||
space = replicate (2 ^ (n - 1)) ' ' |
space = replicate (2 ^ (n - 1)) ' ' |
||
main = mapM_ putStrLn $ sierpinski 4</ |
main = mapM_ putStrLn $ sierpinski 4</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,933: | Line 2,933: | ||
We can see how the approach above (centering a preceding block over two duplicates) generates a framing rectangle at each stage, by making the right padding (plus the extra space between duplicates) more distinct and visible: |
We can see how the approach above (centering a preceding block over two duplicates) generates a framing rectangle at each stage, by making the right padding (plus the extra space between duplicates) more distinct and visible: |
||
< |
<syntaxhighlight lang="haskell">import Data.List (intercalate) |
||
sierpinski :: Int -> [String] |
sierpinski :: Int -> [String] |
||
Line 2,946: | Line 2,946: | ||
main :: IO () |
main :: IO () |
||
main = mapM_ putStrLn $ sierpinski 4</ |
main = mapM_ putStrLn $ sierpinski 4</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> ▲--------------- |
<pre> ▲--------------- |
||
Line 2,967: | Line 2,967: | ||
Using bitwise and between x and y coords: |
Using bitwise and between x and y coords: |
||
< |
<syntaxhighlight lang="haskell">import Data.Bits ((.&.)) |
||
sierpinski n = map row [m, m-1 .. 0] where |
sierpinski n = map row [m, m-1 .. 0] where |
||
Line 2,975: | Line 2,975: | ||
| otherwise = " " |
| otherwise = " " |
||
main = mapM_ putStrLn $ sierpinski 4</ |
main = mapM_ putStrLn $ sierpinski 4</syntaxhighlight> |
||
{{Trans|JavaScript}} |
{{Trans|JavaScript}} |
||
< |
<syntaxhighlight lang="haskell">import Data.List (intersperse) |
||
-- Top down, each row after the first is an XOR / Rule90 rewrite. |
-- Top down, each row after the first is an XOR / Rule90 rewrite. |
||
Line 3,003: | Line 3,003: | ||
main :: IO () |
main :: IO () |
||
main = putStr $ sierpinski 4</ |
main = putStr $ sierpinski 4</syntaxhighlight> |
||
Or simply as a right fold: |
Or simply as a right fold: |
||
< |
<syntaxhighlight lang="haskell">sierpinski :: Int -> [String] |
||
sierpinski n = |
sierpinski n = |
||
foldr |
foldr |
||
Line 3,023: | Line 3,023: | ||
main :: IO () |
main :: IO () |
||
main = (putStrLn . unlines . sierpinski) 4</ |
main = (putStrLn . unlines . sierpinski) 4</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 3,044: | Line 3,044: | ||
=={{header|Haxe}}== |
=={{header|Haxe}}== |
||
< |
<syntaxhighlight lang="haxe">class Main |
||
{ |
{ |
||
static function main() |
static function main() |
||
Line 3,078: | Line 3,078: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Hoon}}== |
=={{header|Hoon}}== |
||
< |
<syntaxhighlight lang="hoon">|= n=@ud |
||
=+ m=0 |
=+ m=0 |
||
=+ o=(reap 1 '*') |
=+ o=(reap 1 '*') |
||
Line 3,089: | Line 3,089: | ||
++ top (turn o |=(l=@t (rap 3 gap l gap ~))) |
++ top (turn o |=(l=@t (rap 3 gap l gap ~))) |
||
++ bot (turn o |=(l=@t (rap 3 l ' ' l ~))) |
++ bot (turn o |=(l=@t (rap 3 l ' ' l ~))) |
||
--</ |
--</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
This is a text based adaption of a program from the IPL and Icon Graphics book. The triangle is presented with a twist. Based on an idea from "Chaos and Fractals" by Peitgen, Jurgens, and Saupe. |
This is a text based adaption of a program from the IPL and Icon Graphics book. The triangle is presented with a twist. Based on an idea from "Chaos and Fractals" by Peitgen, Jurgens, and Saupe. |
||
< |
<syntaxhighlight lang="icon"># text based adaptaion of |
||
procedure main(A) |
procedure main(A) |
||
Line 3,107: | Line 3,107: | ||
writes((y=1,"\n")|"",canvas[x,y]," ") # print |
writes((y=1,"\n")|"",canvas[x,y]," ") # print |
||
end</ |
end</syntaxhighlight> |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
Line 3,126: | Line 3,126: | ||
=={{header|IDL}}== |
=={{header|IDL}}== |
||
The only 'special' thing here is that the math is done in a byte array, filled with the numbers 32 and 42 and then output through a "<tt>string(array)</tt>" which prints the ascii representation of each individual element in the array. |
The only 'special' thing here is that the math is done in a byte array, filled with the numbers 32 and 42 and then output through a "<tt>string(array)</tt>" which prints the ascii representation of each individual element in the array. |
||
< |
<syntaxhighlight lang="idl">pro sierp,n |
||
s = (t = bytarr(3+2^(n+1))+32b) |
s = (t = bytarr(3+2^(n+1))+32b) |
||
t[2^n+1] = 42b |
t[2^n+1] = 42b |
||
Line 3,133: | Line 3,133: | ||
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b |
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
There are any number of succinct ways to produce this in J. |
There are any number of succinct ways to produce this in J. |
||
Here's one that exploits self-similarity: |
Here's one that exploits self-similarity: |
||
< |
<syntaxhighlight lang="j"> |. _31]\ ,(,.~ , ])^:4 ,: '* '</syntaxhighlight> |
||
Here, (,.~ , ])^:4 ,: '* ' is the basic structure (with 4 iterations) and the rest of it is just formatting. |
Here, (,.~ , ])^:4 ,: '* ' is the basic structure (with 4 iterations) and the rest of it is just formatting. |
||
Here's one that leverages the relationship between Sierpinski's and Pascal's triangles: |
Here's one that leverages the relationship between Sierpinski's and Pascal's triangles: |
||
< |
<syntaxhighlight lang="j"> ' *' {~ '1' = (- |."_1 [: ": 2 | !/~) i._16</syntaxhighlight> |
||
Here, !/~ i._16 gives us [[Pascal's_triangle|pascal's triangle]] (and we want a power of 2 (or, for the formatting we are using here a negative of a power of 2) for the size of the square in which contains the triangle, and (2 + |/~) i._16 is a [[Boolean_values#J|boolean]] representation where the 1s correspond to odd values in pascal's triangle, and the rest is just formatting. |
Here, !/~ i._16 gives us [[Pascal's_triangle|pascal's triangle]] (and we want a power of 2 (or, for the formatting we are using here a negative of a power of 2) for the size of the square in which contains the triangle, and (2 + |/~) i._16 is a [[Boolean_values#J|boolean]] representation where the 1s correspond to odd values in pascal's triangle, and the rest is just formatting. |
||
Line 3,152: | Line 3,152: | ||
Replace translations. |
Replace translations. |
||
Recursive solution. |
Recursive solution. |
||
< |
<syntaxhighlight lang="java"> |
||
public class SierpinskiTriangle { |
public class SierpinskiTriangle { |
||
Line 3,198: | Line 3,198: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 3,222: | Line 3,222: | ||
=={{header|JavaFX Script}}== |
=={{header|JavaFX Script}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="javafx">function sierpinski(n : Integer) { |
||
var down = ["*"]; |
var down = ["*"]; |
||
var space = " "; |
var space = " "; |
||
Line 3,235: | Line 3,235: | ||
} |
} |
||
sierpinski(4);</ |
sierpinski(4);</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Line 3,245: | Line 3,245: | ||
mapping the binary pattern to centred strings. |
mapping the binary pattern to centred strings. |
||
< |
<syntaxhighlight lang="javascript">(function (order) { |
||
// Sierpinski triangle of order N constructed as |
// Sierpinski triangle of order N constructed as |
||
Line 3,303: | Line 3,303: | ||
})(4); |
})(4); |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output (N=4) |
Output (N=4) |
||
Line 3,326: | Line 3,326: | ||
====Imperative==== |
====Imperative==== |
||
< |
<syntaxhighlight lang="javascript">function triangle(o) { |
||
var n = 1 << o, |
var n = 1 << o, |
||
line = new Array(2 * n), |
line = new Array(2 * n), |
||
Line 3,346: | Line 3,346: | ||
document.write("<pre>\n"); |
document.write("<pre>\n"); |
||
triangle(6); |
triangle(6); |
||
document.write("</pre>");</ |
document.write("</pre>");</syntaxhighlight> |
||
===ES6=== |
===ES6=== |
||
Directly in terms of the built-in Array methods '''.map''', '''.reduce''', and '''.from''', and without much abstraction, possibly at the cost of some legibility: |
Directly in terms of the built-in Array methods '''.map''', '''.reduce''', and '''.from''', and without much abstraction, possibly at the cost of some legibility: |
||
< |
<syntaxhighlight lang="javascript">(() => { |
||
"use strict"; |
"use strict"; |
||
Line 3,375: | Line 3,375: | ||
// ---------------------- TEST ----------------------- |
// ---------------------- TEST ----------------------- |
||
return sierpinski(4); |
return sierpinski(4); |
||
})();</ |
})();</syntaxhighlight> |
||
{{Trans|Haskell}} |
{{Trans|Haskell}} |
||
Centering any preceding triangle block over two adjacent duplicates: |
Centering any preceding triangle block over two adjacent duplicates: |
||
< |
<syntaxhighlight lang="javascript">(() => { |
||
"use strict"; |
"use strict"; |
||
Line 3,448: | Line 3,448: | ||
// ---------------------- TEST ----------------------- |
// ---------------------- TEST ----------------------- |
||
return main(); |
return main(); |
||
})();</ |
})();</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> ▲--------------- |
<pre> ▲--------------- |
||
Line 3,469: | Line 3,469: | ||
Or constructed as 2^N lines of Pascal's triangle mod 2, |
Or constructed as 2^N lines of Pascal's triangle mod 2, |
||
and mapped to centred {1:asterisk, 0:space} strings. |
and mapped to centred {1:asterisk, 0:space} strings. |
||
< |
<syntaxhighlight lang="javascript">(() => { |
||
"use strict"; |
"use strict"; |
||
Line 3,537: | Line 3,537: | ||
// MAIN --- |
// MAIN --- |
||
return main(); |
return main(); |
||
})();</ |
})();</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> * |
<pre> * |
||
Line 3,561: | Line 3,561: | ||
'''Preliminaries''' |
'''Preliminaries''' |
||
< |
<syntaxhighlight lang="jq">def elementwise(f): |
||
transpose | map(f) ; |
transpose | map(f) ; |
||
Line 3,581: | Line 3,581: | ||
| (map(length) | min) as $min |
| (map(length) | min) as $min |
||
| map( .[:$min] ) | elementwise(min) | toi |
| map( .[:$min] ) | elementwise(min) | toi |
||
end;</ |
end;</syntaxhighlight> |
||
<syntaxhighlight lang="jq"> |
|||
<lang jq> |
|||
def sierpinski: |
def sierpinski: |
||
pow(2; .) as $size |
pow(2; .) as $size |
||
Line 3,589: | Line 3,589: | ||
. + (if ([$x,$y]|bitwise_and) == 0 then "* " else " " end)); |
. + (if ([$x,$y]|bitwise_and) == 0 then "* " else " " end)); |
||
4 | sierpinski</ |
4 | sierpinski</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
As elsewhere. |
As elsewhere. |
||
Line 3,596: | Line 3,596: | ||
{{works with|Julia|0.6}} |
{{works with|Julia|0.6}} |
||
< |
<syntaxhighlight lang="julia">function sierpinski(n, token::AbstractString="*") |
||
x = fill(token, 1, 1) |
x = fill(token, 1, 1) |
||
for _ in 1:n |
for _ in 1:n |
||
Line 3,613: | Line 3,613: | ||
end |
end |
||
sierpinski(4) |> printsierpinski</ |
sierpinski(4) |> printsierpinski</syntaxhighlight> |
||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
const val ORDER = 4 |
const val ORDER = 4 |
||
Line 3,628: | Line 3,628: | ||
println() |
println() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,651: | Line 3,651: | ||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
< |
<syntaxhighlight lang="lb">nOrder=4 |
||
call triangle 1, 1, nOrder |
call triangle 1, 1, nOrder |
||
end |
end |
||
Line 3,665: | Line 3,665: | ||
call triangle x+length*2, y+length, n |
call triangle x+length*2, y+length, n |
||
END IF |
END IF |
||
END SUB</ |
END SUB</syntaxhighlight> |
||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
< |
<syntaxhighlight lang="logo">; Print rows of the triangle from 0 to :limit inclusive. |
||
; limit=15 gives the order 4 form per the task. |
; limit=15 gives the order 4 form per the task. |
||
; The range of :y is arbitrary, any rows of the triangle can be printed. |
; The range of :y is arbitrary, any rows of the triangle can be printed. |
||
Line 3,681: | Line 3,681: | ||
] |
] |
||
print [] |
print [] |
||
]</ |
]</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Ported from the list-comprehension Python version. |
Ported from the list-comprehension Python version. |
||
< |
<syntaxhighlight lang="lua">function sierpinski(depth) |
||
lines = {} |
lines = {} |
||
lines[1] = '*' |
lines[1] = '*' |
||
Line 3,702: | Line 3,702: | ||
end |
end |
||
print(sierpinski(4))</ |
print(sierpinski(4))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,724: | Line 3,724: | ||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple">S := proc(n) |
||
local i, j, values, position; |
local i, j, values, position; |
||
values := [ seq(" ",i=1..2^n-1), "*" ]; |
values := [ seq(" ",i=1..2^n-1), "*" ]; |
||
Line 3,738: | Line 3,738: | ||
printf("%s\n",cat(op(convert(values, list)))); |
printf("%s\n",cat(op(convert(values, list)))); |
||
end do: |
end do: |
||
end proc:</ |
end proc:</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,761: | Line 3,761: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Cellular automaton (rule 90) based solution: |
Cellular automaton (rule 90) based solution: |
||
< |
<syntaxhighlight lang="mathematica">n=4;Grid[CellularAutomaton[90,{{1},0},2^n-1]/.{0->" ",1->"*"},ItemSize->All]</syntaxhighlight> |
||
Using built-in function: |
Using built-in function: |
||
<lang |
<syntaxhighlight lang="mathematica">SierpinskiMesh[3]</syntaxhighlight> |
||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
STRING was introduced in version R2016b. |
STRING was introduced in version R2016b. |
||
< |
<syntaxhighlight lang="matlab">n = 4; |
||
d = string('*'); |
d = string('*'); |
||
for k = 0 : n - 1 |
for k = 0 : n - 1 |
||
Line 3,774: | Line 3,774: | ||
end |
end |
||
disp(d.join(char(10))) |
disp(d.join(char(10))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,795: | Line 3,795: | ||
</pre> |
</pre> |
||
===Cellular Automaton Version=== |
===Cellular Automaton Version=== |
||
< |
<syntaxhighlight lang="matlab">n = 2 ^ 4 - 1; |
||
tr = + ~(-n : n); |
tr = + ~(-n : n); |
||
for k = 1:n |
for k = 1:n |
||
tr(k + 1, :) = bitget(90, 1 + filter2([4 2 1], tr(k, :))); |
tr(k + 1, :) = bitget(90, 1 + filter2([4 2 1], tr(k, :))); |
||
end |
end |
||
char(10 * tr + 32)</ |
char(10 * tr + 32)</syntaxhighlight> |
||
===Mixed Version=== |
===Mixed Version=== |
||
< |
<syntaxhighlight lang="matlab">spy(mod(abs(pascal(32,1)),2)==1)</syntaxhighlight> |
||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref symbols nobinary |
options replace format comments java crossref symbols nobinary |
||
Line 3,846: | Line 3,846: | ||
end row |
end row |
||
return |
return |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,869: | Line 3,869: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="nim">const size = 1 shl 4 - 1 |
||
for y in countdown(size, 0): |
for y in countdown(size, 0): |
||
Line 3,879: | Line 3,879: | ||
else: |
else: |
||
stdout.write "* " |
stdout.write "* " |
||
stdout.write "\n"</ |
stdout.write "\n"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,900: | Line 3,900: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">let sierpinski n = |
||
let rec loop down space n = |
let rec loop down space n = |
||
if n = 0 then |
if n = 0 then |
||
Line 3,912: | Line 3,912: | ||
let () = |
let () = |
||
List.iter print_endline (sierpinski 4)</ |
List.iter print_endline (sierpinski 4)</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 3,920: | Line 3,920: | ||
automat(rule, n) runs cellular automaton for rule "rule" for n generations. |
automat(rule, n) runs cellular automaton for rule "rule" for n generations. |
||
< |
<syntaxhighlight lang="oforth">: nextGen(l, r) |
||
| i | |
| i | |
||
StringBuffer new |
StringBuffer new |
||
Line 3,935: | Line 3,935: | ||
: sierpinskiTriangle(n) |
: sierpinskiTriangle(n) |
||
90 4 n * automat ;</ |
90 4 n * automat ;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,961: | Line 3,961: | ||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
< |
<syntaxhighlight lang="oz">declare |
||
fun {NextTriangle Triangle} |
fun {NextTriangle Triangle} |
||
Sp = {Spaces {Length Triangle}} |
Sp = {Spaces {Length Triangle}} |
||
Line 3,979: | Line 3,979: | ||
SierpinskiTriangles = {Iterate NextTriangle ["*"]} |
SierpinskiTriangles = {Iterate NextTriangle ["*"]} |
||
in |
in |
||
{ForAll {Nth SierpinskiTriangles 5} System.showInfo}</ |
{ForAll {Nth SierpinskiTriangles 5} System.showInfo}</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="parigp">Sierpinski(n)={ |
||
my(s=2^n-1); |
my(s=2^n-1); |
||
forstep(y=s,0,-1, |
forstep(y=s,0,-1, |
||
Line 3,993: | Line 3,993: | ||
) |
) |
||
}; |
}; |
||
Sierpinski(4)</ |
Sierpinski(4)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> * |
<pre> * |
||
Line 4,015: | Line 4,015: | ||
{{trans|C}} |
{{trans|C}} |
||
{{works with|Free Pascal}} |
{{works with|Free Pascal}} |
||
< |
<syntaxhighlight lang="pascal">program Sierpinski; |
||
function ipow(b, n : Integer) : Integer; |
function ipow(b, n : Integer) : Integer; |
||
Line 4,032: | Line 4,032: | ||
else |
else |
||
truth := false |
truth := false |
||
end;</ |
end;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="pascal">function rule_90(ev : String) : String; |
||
var |
var |
||
l, i : Integer; |
l, i : Integer; |
||
Line 4,074: | Line 4,074: | ||
writeln(b) |
writeln(b) |
||
end |
end |
||
end;</ |
end;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="pascal">begin |
||
triangle(4) |
triangle(4) |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
===version 1=== |
===version 1=== |
||
< |
<syntaxhighlight lang="perl">sub sierpinski { |
||
my ($n) = @_; |
my ($n) = @_; |
||
my @down = '*'; |
my @down = '*'; |
||
Line 4,093: | Line 4,093: | ||
} |
} |
||
print "$_\n" foreach sierpinski 4;</ |
print "$_\n" foreach sierpinski 4;</syntaxhighlight> |
||
===one-liner=== |
===one-liner=== |
||
< |
<syntaxhighlight lang="perl"> |
||
perl -le '$l=40;$l2="!" x $l;substr+($l2^=$l2),$l/2,1,"\xFF";for(1..16){local $_=$l2;y/\0\xFF/ */;print;($lf,$rt)=map{substr $l2 x 2,$_%$l,$l;}1,-1;$l2=$lf^$rt;select undef,undef,undef,.1;}'</ |
perl -le '$l=40;$l2="!" x $l;substr+($l2^=$l2),$l/2,1,"\xFF";for(1..16){local $_=$l2;y/\0\xFF/ */;print;($lf,$rt)=map{substr $l2 x 2,$_%$l,$l;}1,-1;$l2=$lf^$rt;select undef,undef,undef,.1;}'</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{Trans|C}} |
{{Trans|C}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">sierpinski</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">procedure</span> <span style="color: #000000;">sierpinski</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #004080;">integer</span> <span style="color: #000000;">lim</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> |
<span style="color: #004080;">integer</span> <span style="color: #000000;">lim</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> |
||
Line 4,116: | Line 4,116: | ||
<span style="color: #000000;">sierpinski</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">sierpinski</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre style="font-size: 2px"> |
<pre style="font-size: 2px"> |
||
Line 4,184: | Line 4,184: | ||
=={{header|Phixmonti}}== |
=={{header|Phixmonti}}== |
||
< |
<syntaxhighlight lang="phixmonti">def sierpinski |
||
2 swap power 1 - var lim |
2 swap power 1 - var lim |
||
lim 0 -1 3 tolist for |
lim 0 -1 3 tolist for |
||
Line 4,198: | Line 4,198: | ||
5 for |
5 for |
||
sierpinski |
sierpinski |
||
endfor</ |
endfor</syntaxhighlight> |
||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
Line 4,204: | Line 4,204: | ||
{{Trans|JavaScript}} |
{{Trans|JavaScript}} |
||
< |
<syntaxhighlight lang="php"><?php |
||
function sierpinskiTriangle($order) { |
function sierpinskiTriangle($order) { |
||
Line 4,228: | Line 4,228: | ||
sierpinskiTriangle(4); |
sierpinskiTriangle(4); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 4,251: | Line 4,251: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
{{trans|E}} |
{{trans|E}} |
||
< |
<syntaxhighlight lang="picat">go => |
||
foreach(N in 1..4) |
foreach(N in 1..4) |
||
sierpinski(N), |
sierpinski(N), |
||
Line 4,266: | Line 4,266: | ||
end, |
end, |
||
nl |
nl |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,306: | Line 4,306: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="picolisp">(de sierpinski (N) |
||
(let (D '("*") S " ") |
(let (D '("*") S " ") |
||
(do N |
(do N |
||
Line 4,316: | Line 4,316: | ||
D ) ) |
D ) ) |
||
(mapc prinl (sierpinski 4))</ |
(mapc prinl (sierpinski 4))</syntaxhighlight> |
||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
< |
<syntaxhighlight lang="pl/i">sierpinski: procedure options (main); /* 2010-03-30 */ |
||
declare t (79,79) char (1); |
declare t (79,79) char (1); |
||
declare (i, j, k) fixed binary; |
declare (i, j, k) fixed binary; |
||
Line 4,367: | Line 4,367: | ||
end make_triangle; |
end make_triangle; |
||
end sierpinski;</ |
end sierpinski;</syntaxhighlight> |
||
=={{header|PL/M}}== |
=={{header|PL/M}}== |
||
< |
<syntaxhighlight lang="plm">100H: |
||
DECLARE ORDER LITERALLY '4'; |
DECLARE ORDER LITERALLY '4'; |
||
Line 4,406: | Line 4,406: | ||
CALL BDOS(0,0); |
CALL BDOS(0,0); |
||
EOF</ |
EOF</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> * |
<pre> * |
||
Line 4,428: | Line 4,428: | ||
Solution using line buffer in an integer array oline, 0 represents ' ' |
Solution using line buffer in an integer array oline, 0 represents ' ' |
||
(space), 1 represents '*' (star). |
(space), 1 represents '*' (star). |
||
< |
<syntaxhighlight lang="pop11">define triangle(n); |
||
lvars k = 2**n, j, l, oline, nline; |
lvars k = 2**n, j, l, oline, nline; |
||
initv(2*k+3) -> oline; |
initv(2*k+3) -> oline; |
||
Line 4,448: | Line 4,448: | ||
enddefine; |
enddefine; |
||
triangle(4);</ |
triangle(4);</syntaxhighlight> |
||
Alternative solution, keeping all triangle as list of strings |
Alternative solution, keeping all triangle as list of strings |
||
< |
<syntaxhighlight lang="pop11">define triangle2(n); |
||
lvars acc = ['*'], spaces = ' ', j; |
lvars acc = ['*'], spaces = ' ', j; |
||
for j from 1 to n do |
for j from 1 to n do |
||
Line 4,461: | Line 4,461: | ||
enddefine; |
enddefine; |
||
triangle2(4);</ |
triangle2(4);</syntaxhighlight> |
||
=={{header|PostScript}}== |
=={{header|PostScript}}== |
||
This draws the triangles in a string-rewrite fashion, where all edges form a single polyline. 9 page document showing progession. |
This draws the triangles in a string-rewrite fashion, where all edges form a single polyline. 9 page document showing progession. |
||
< |
<syntaxhighlight lang="postscript">%!PS-Adobe-3.0 |
||
%%BoundingBox 0 0 300 300 |
%%BoundingBox 0 0 300 300 |
||
Line 4,479: | Line 4,479: | ||
0 1 8 { 300 300 scale 0 1 12 div moveto |
0 1 8 { 300 300 scale 0 1 12 div moveto |
||
X + F + F fill showpage } for |
X + F + F fill showpage } for |
||
%%EOF</ |
%%EOF</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
{{Trans|JavaScript}} |
{{Trans|JavaScript}} |
||
< |
<syntaxhighlight lang="powershell">function triangle($o) { |
||
$n = [Math]::Pow(2, $o) |
$n = [Math]::Pow(2, $o) |
||
$line = ,' '*(2*$n+1) |
$line = ,' '*(2*$n+1) |
||
Line 4,503: | Line 4,503: | ||
$line[$n+$i+1] = '█' |
$line[$n+$i+1] = '█' |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Processing}}== |
=={{header|Processing}}== |
||
===Characters in drawing canvas version=== |
===Characters in drawing canvas version=== |
||
< |
<syntaxhighlight lang="java">void setup() { |
||
size(410, 230); |
size(410, 230); |
||
background(255); |
background(255); |
||
Line 4,522: | Line 4,522: | ||
sTriangle(x+l*2, y+l, l/2, n-1); |
sTriangle(x+l*2, y+l, l/2, n-1); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Text in console version=== |
===Text in console version=== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="java">void setup() { |
||
print(getSierpinskiTriangle(3)); |
print(getSierpinskiTriangle(3)); |
||
} |
} |
||
Line 4,561: | Line 4,561: | ||
return ns; |
return ns; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
Works with SWI-Prolog; |
Works with SWI-Prolog; |
||
< |
<syntaxhighlight lang="prolog">sierpinski_triangle(N) :- |
||
Len is 2 ** (N+1) - 1, |
Len is 2 ** (N+1) - 1, |
||
length(L, Len), |
length(L, Len), |
||
Line 4,605: | Line 4,605: | ||
rule_90(' ',' ','*', '*'). |
rule_90(' ',' ','*', '*'). |
||
rule_90(' ',' ',' ', ' '). |
rule_90(' ',' ',' ', ' '). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> ?- sierpinski_triangle(4). |
<pre> ?- sierpinski_triangle(4). |
||
Line 4,627: | Line 4,627: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">Procedure Triangle (X,Y, Length, N) |
||
If N = 0 |
If N = 0 |
||
DrawText( Y,X, "*",#Blue) |
DrawText( Y,X, "*",#Blue) |
||
Line 4,646: | Line 4,646: | ||
Repeat |
Repeat |
||
Until WaitWindowEvent()=#PB_Event_CloseWindow |
Until WaitWindowEvent()=#PB_Event_CloseWindow |
||
End</ |
End</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">def sierpinski(n): |
||
d = ["*"] |
d = ["*"] |
||
for i in xrange(n): |
for i in xrange(n): |
||
Line 4,656: | Line 4,656: | ||
return d |
return d |
||
print "\n".join(sierpinski(4))</ |
print "\n".join(sierpinski(4))</syntaxhighlight> |
||
Or, using fold / reduce {{works with|Python|3.x}} |
Or, using fold / reduce {{works with|Python|3.x}} |
||
< |
<syntaxhighlight lang="python">import functools |
||
def sierpinski(n): |
def sierpinski(n): |
||
Line 4,670: | Line 4,670: | ||
return functools.reduce(aggregate, range(n), ["*"]) |
return functools.reduce(aggregate, range(n), ["*"]) |
||
print("\n".join(sierpinski(4)))</ |
print("\n".join(sierpinski(4)))</syntaxhighlight> |
||
and fold/reduce, wrapped as concatMap, can provide the list comprehensions too: |
and fold/reduce, wrapped as concatMap, can provide the list comprehensions too: |
||
< |
<syntaxhighlight lang="python">'''Sierpinski triangle''' |
||
from functools import reduce |
from functools import reduce |
||
Line 4,703: | Line 4,703: | ||
print(sierpinski(4))</ |
print(sierpinski(4))</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> * |
<pre> * |
||
Line 4,724: | Line 4,724: | ||
Use Python's long integer and bit operator to make an infinite triangle: |
Use Python's long integer and bit operator to make an infinite triangle: |
||
< |
<syntaxhighlight lang="python">x = 1 |
||
while True: |
while True: |
||
print(bin(x)[2:].replace('0', ' ')) |
print(bin(x)[2:].replace('0', ' ')) |
||
x ^= x<<1</ |
x ^= x<<1</syntaxhighlight> |
||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
Line 4,733: | Line 4,733: | ||
{{trans|Forth}} |
{{trans|Forth}} |
||
< |
<syntaxhighlight lang="quackery"> [ [ dup 1 & |
||
iff char * else space |
iff char * else space |
||
emit |
emit |
||
Line 4,747: | Line 4,747: | ||
2drop ] is triangle ( order --> ) |
2drop ] is triangle ( order --> ) |
||
4 triangle</ |
4 triangle</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,771: | Line 4,771: | ||
=={{header|R}}== |
=={{header|R}}== |
||
Based on C# but using some of R's functionality to abbreviate code where possible. |
Based on C# but using some of R's functionality to abbreviate code where possible. |
||
< |
<syntaxhighlight lang="r">sierpinski.triangle = function(n) { |
||
len <- 2^(n+1) |
len <- 2^(n+1) |
||
b <- c(rep(FALSE,len/2),TRUE,rep(FALSE,len/2)) |
b <- c(rep(FALSE,len/2),TRUE,rep(FALSE,len/2)) |
||
Line 4,783: | Line 4,783: | ||
} |
} |
||
} |
} |
||
sierpinski.triangle(5)</ |
sierpinski.triangle(5)</syntaxhighlight> |
||
Shortened to a function of one line. |
Shortened to a function of one line. |
||
< |
<syntaxhighlight lang="r">sierpinski.triangle = function(n) { |
||
c(paste(ifelse(b<<- c(rep(FALSE,2^(n+1)/2),TRUE,rep(FALSE,2^(n+1)/2)),"*"," "),collapse=""),replicate(2^n-1,paste(ifelse(b<<-xor(c(FALSE,b[1:2^(n+1)]),c(b[2:(2^(n+1)+1)],FALSE)),"*"," "),collapse=""))) |
c(paste(ifelse(b<<- c(rep(FALSE,2^(n+1)/2),TRUE,rep(FALSE,2^(n+1)/2)),"*"," "),collapse=""),replicate(2^n-1,paste(ifelse(b<<-xor(c(FALSE,b[1:2^(n+1)]),c(b[2:(2^(n+1)+1)],FALSE)),"*"," "),collapse=""))) |
||
} |
} |
||
cat(sierpinski.triangle(5),sep="\n")</ |
cat(sierpinski.triangle(5),sep="\n")</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
<syntaxhighlight lang="racket"> |
|||
<lang Racket> |
|||
#lang racket |
#lang racket |
||
(define (sierpinski n) |
(define (sierpinski n) |
||
Line 4,803: | Line 4,803: | ||
(map (λ(x) (~a x " " x)) prev))))) |
(map (λ(x) (~a x " " x)) prev))))) |
||
(for-each displayln (sierpinski 5)) |
(for-each displayln (sierpinski 5)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
<lang |
<syntaxhighlight lang="raku" line>sub sierpinski ($n) { |
||
my @down = '*'; |
my @down = '*'; |
||
my $space = ' '; |
my $space = ' '; |
||
Line 4,818: | Line 4,818: | ||
} |
} |
||
.say for sierpinski 4;</ |
.say for sierpinski 4;</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program constructs and displays a Sierpinski triangle of up to around order 10k.*/ |
||
parse arg n mark . /*get the order of Sierpinski triangle.*/ |
parse arg n mark . /*get the order of Sierpinski triangle.*/ |
||
if n=='' | n=="," then n=4 /*Not specified? Then use the default.*/ |
if n=='' | n=="," then n=4 /*Not specified? Then use the default.*/ |
||
Line 4,837: | Line 4,837: | ||
say z /*display a line of the triangle. */ |
say z /*display a line of the triangle. */ |
||
end /*j*/ /* [↑] finished showing triangle. */ |
end /*j*/ /* [↑] finished showing triangle. */ |
||
/*stick a fork in it, we're all done. */</ |
/*stick a fork in it, we're all done. */</syntaxhighlight> |
||
'''output''' when using the default input of order: <tt> 4 </tt> |
'''output''' when using the default input of order: <tt> 4 </tt> |
||
Line 5,042: | Line 5,042: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
# Project : Sierpinski triangle |
# Project : Sierpinski triangle |
||
Line 5,065: | Line 5,065: | ||
triangle(x+length*2, y+length, n) |
triangle(x+length*2, y+length, n) |
||
ok |
ok |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 5,088: | Line 5,088: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
From the command line: |
From the command line: |
||
< |
<syntaxhighlight lang="ruby">ruby -le'16.times{|y|print" "*(15-y),*(0..y).map{|x|~y&x>0?" ":" *"}}'</syntaxhighlight> |
||
or, {{trans|Python}} |
or, {{trans|Python}} |
||
< |
<syntaxhighlight lang="ruby">def sierpinski_triangle(n) |
||
triangle = ["*"] |
triangle = ["*"] |
||
n.times do |i| |
n.times do |i| |
||
Line 5,101: | Line 5,101: | ||
end |
end |
||
puts sierpinski_triangle(4)</ |
puts sierpinski_triangle(4)</syntaxhighlight> |
||
Using fold / reduce (aka. inject): |
Using fold / reduce (aka. inject): |
||
< |
<syntaxhighlight lang="ruby">def sierpinski_triangle(n) |
||
(0...n).inject(["*"]) {|triangle, i| |
(0...n).inject(["*"]) {|triangle, i| |
||
space = " " * (2**i) |
space = " " * (2**i) |
||
Line 5,112: | Line 5,112: | ||
end |
end |
||
puts sierpinski_triangle(4)</ |
puts sierpinski_triangle(4)</syntaxhighlight> |
||
=={{header|Run BASIC}}== |
=={{header|Run BASIC}}== |
||
< |
<syntaxhighlight lang="runbasic">nOrder=4 |
||
dim xy$(40) |
dim xy$(40) |
||
for i = 1 to 40 |
for i = 1 to 40 |
||
Line 5,136: | Line 5,136: | ||
call triangle x+length*2, y+length, n |
call triangle x+length*2, y+length, n |
||
END IF |
END IF |
||
END SUB</ |
END SUB</syntaxhighlight> |
||
<pre> * |
<pre> * |
||
* * |
* * |
||
Line 5,154: | Line 5,154: | ||
* * * * * * * * * * * * * * * *</pre> |
* * * * * * * * * * * * * * * *</pre> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang="rust"> |
||
use std::iter::repeat; |
use std::iter::repeat; |
||
Line 5,192: | Line 5,192: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,215: | Line 5,215: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
The Ruby command-line version (on Windows): |
The Ruby command-line version (on Windows): |
||
< |
<syntaxhighlight lang="scala">scala -e "for(y<-0 to 15){println(\" \"*(15-y)++(0 to y).map(x=>if((~y&x)>0)\" \"else\" *\")mkString)}"</syntaxhighlight> |
||
The Forth version: |
The Forth version: |
||
< |
<syntaxhighlight lang="scala">def sierpinski(n: Int) { |
||
def star(n: Long) = if ((n & 1L) == 1L) "*" else " " |
def star(n: Long) = if ((n & 1L) == 1L) "*" else " " |
||
def stars(n: Long): String = if (n == 0L) "" else star(n) + " " + stars(n >> 1) |
def stars(n: Long): String = if (n == 0L) "" else star(n) + " " + stars(n >> 1) |
||
Line 5,227: | Line 5,227: | ||
(bitmap << 1) ^ bitmap |
(bitmap << 1) ^ bitmap |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
The Haskell version: |
The Haskell version: |
||
< |
<syntaxhighlight lang="scala">def printSierpinski(n: Int) { |
||
def sierpinski(n: Int): List[String] = { |
def sierpinski(n: Int): List[String] = { |
||
lazy val down = sierpinski(n - 1) |
lazy val down = sierpinski(n - 1) |
||
Line 5,241: | Line 5,241: | ||
} |
} |
||
sierpinski(n) foreach println |
sierpinski(n) foreach println |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
< |
<syntaxhighlight lang="scheme">(define (sierpinski n) |
||
(for-each |
(for-each |
||
(lambda (x) (display (list->string x)) (newline)) |
(lambda (x) (display (list->string x)) (newline)) |
||
Line 5,256: | Line 5,256: | ||
(map (lambda (x) (append x (list #\ ) x)) acc)) |
(map (lambda (x) (append x (list #\ ) x)) acc)) |
||
(append spaces spaces) |
(append spaces spaces) |
||
(- n 1))))))</ |
(- n 1))))))</syntaxhighlight> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
||
const func array string: sierpinski (in integer: n) is func |
const func array string: sierpinski (in integer: n) is func |
||
Line 5,286: | Line 5,286: | ||
begin |
begin |
||
writeln(join(sierpinski(4), "\n")); |
writeln(join(sierpinski(4), "\n")); |
||
end func;</ |
end func;</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">func sierpinski_triangle(n) { |
||
var triangle = ['*'] |
var triangle = ['*'] |
||
{ |i| |
{ |i| |
||
Line 5,299: | Line 5,299: | ||
} |
} |
||
say sierpinski_triangle(4)</ |
say sierpinski_triangle(4)</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
<lang>import Foundation |
<syntaxhighlight lang="text">import Foundation |
||
// Easy get/set of charAt |
// Easy get/set of charAt |
||
Line 5,346: | Line 5,346: | ||
line[n + i + 1] = "*" |
line[n + i + 1] = "*" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
proc map {lambda list} { |
proc map {lambda list} { |
||
Line 5,372: | Line 5,372: | ||
} |
} |
||
puts [sierpinski_triangle 4]</ |
puts [sierpinski_triangle 4]</syntaxhighlight> |
||
=={{header|TI-83 BASIC}}== |
=={{header|TI-83 BASIC}}== |
||
Uses Wolfram Rule 90. |
Uses Wolfram Rule 90. |
||
< |
<syntaxhighlight lang="ti83b">PROGRAM:SIRPNSKI |
||
:ClrHome |
:ClrHome |
||
:Output(1,8,"^") |
:Output(1,8,"^") |
||
Line 5,406: | Line 5,406: | ||
:L3→L2 |
:L3→L2 |
||
:End |
:End |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|uBasic/4tH}}== |
=={{header|uBasic/4tH}}== |
||
<lang>Input "Triangle order: ";n |
<syntaxhighlight lang="text">Input "Triangle order: ";n |
||
n = 2^n |
n = 2^n |
||
Line 5,430: | Line 5,430: | ||
Print |
Print |
||
Next |
Next |
||
End</ |
End</syntaxhighlight> |
||
=={{header|Unlambda}}== |
=={{header|Unlambda}}== |
||
< |
<syntaxhighlight lang="unlambda">```ci``s``s`ks``s`k`s``s`kc``s``s``si`kr`k. `k.*k |
||
`k``s``s``s``s`s`k`s``s`ksk`k``s``si`kk`k``s`kkk |
`k``s``s``s``s`s`k`s``s`ksk`k``s``si`kk`k``s`kkk |
||
`k``s`k`s``si`kk``s`kk``s``s``s``si`kk`k`s`k`s``s`ksk`k`s`k`s`k`si``si`k`ki |
`k``s`k`s``si`kk``s`kk``s``s``s``si`kk`k`s`k`s``s`ksk`k`s`k`s`k`si``si`k`ki |
||
`k``s`k`s``si`k`ki``s`kk``s``s``s``si`kk`k`s`k`s`k`si`k`s`k`s``s`ksk``si`k`ki |
`k``s`k`s``si`k`ki``s`kk``s``s``s``si`kk`k`s`k`s`k`si`k`s`k`s``s`ksk``si`k`ki |
||
`k`ki``s`k`s`k`si``s`kkk</ |
`k`ki``s`k`s`k`si``s`kkk</syntaxhighlight> |
||
This produces an infinite, left-justified triangle: |
This produces an infinite, left-justified triangle: |
||
<pre style="height:30ex;overflow:scroll;"> |
<pre style="height:30ex;overflow:scroll;"> |
||
Line 5,480: | Line 5,480: | ||
=={{header|Ursala}}== |
=={{header|Ursala}}== |
||
the straightforward recursive solution |
the straightforward recursive solution |
||
< |
<syntaxhighlight lang="ursala">#import nat |
||
triangle = ~&a^?\<<&>>! ^|RNSiDlrTSPxSxNiCK9xSx4NiCSplrTSPT/~& predecessor</ |
triangle = ~&a^?\<<&>>! ^|RNSiDlrTSPxSxNiCK9xSx4NiCSplrTSPT/~& predecessor</syntaxhighlight> |
||
the cheeky cellular automaton solution |
the cheeky cellular automaton solution |
||
< |
<syntaxhighlight lang="ursala">#import std |
||
#import nat |
#import nat |
||
rule = -$<0,&,0,0,&,0,0,0>@rSS zipp0*ziD iota8 |
rule = -$<0,&,0,0,&,0,0,0>@rSS zipp0*ziD iota8 |
||
evolve "n" = @iNC ~&x+ rep"n" ^C\~& @h rule*+ swin3+ :/0+ --<0> |
evolve "n" = @iNC ~&x+ rep"n" ^C\~& @h rule*+ swin3+ :/0+ --<0> |
||
sierpinski = iota; --<&>@NS; iota; ^H/evolve@z @NS ^T/~& :/&</ |
sierpinski = iota; --<&>@NS; iota; ^H/evolve@z @NS ^T/~& :/&</syntaxhighlight> |
||
an example of each (converting from booleans to characters) |
an example of each (converting from booleans to characters) |
||
< |
<syntaxhighlight lang="ursala">#show+ |
||
examples = mat0 ~&?(`*!,` !)*** <sierpinski3,triangle4></ |
examples = mat0 ~&?(`*!,` !)*** <sierpinski3,triangle4></syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre style="height:30ex;overflow:scroll;"> |
<pre style="height:30ex;overflow:scroll;"> |
||
Line 5,524: | Line 5,524: | ||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
{{Trans|Phix}}< |
{{Trans|Phix}}<syntaxhighlight lang="vb">Sub sierpinski(n As Integer) |
||
Dim lim As Integer: lim = 2 ^ n - 1 |
Dim lim As Integer: lim = 2 ^ n - 1 |
||
For y = lim To 0 Step -1 |
For y = lim To 0 Step -1 |
||
Line 5,539: | Line 5,539: | ||
sierpinski i |
sierpinski i |
||
Next i |
Next i |
||
End Sub</ |
End Sub</syntaxhighlight>{{out}} |
||
<pre style="font-size: 4px"> |
<pre style="font-size: 4px"> |
||
# |
# |
||
Line 5,667: | Line 5,667: | ||
=={{header|VBScript}}== |
=={{header|VBScript}}== |
||
{{trans|PowerShell}} |
{{trans|PowerShell}} |
||
<syntaxhighlight lang="vb"> |
|||
<lang vb> |
|||
Sub triangle(o) |
Sub triangle(o) |
||
n = 2 ^ o |
n = 2 ^ o |
||
Line 5,695: | Line 5,695: | ||
triangle(4) |
triangle(4) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Vedit macro language}}== |
=={{header|Vedit macro language}}== |
||
Line 5,702: | Line 5,702: | ||
The macro writes the fractal into an edit buffer where it can be viewed and saved to file if required. |
The macro writes the fractal into an edit buffer where it can be viewed and saved to file if required. |
||
This allows creating images larger than screen, the size is only limited by free disk space. |
This allows creating images larger than screen, the size is only limited by free disk space. |
||
< |
<syntaxhighlight lang="vedit">#3 = 16 // size (height) of the triangle |
||
Buf_Switch(Buf_Free) // Open a new buffer for output |
Buf_Switch(Buf_Free) // Open a new buffer for output |
||
Ins_Char(' ', COUNT, #3*2+2) // fill first line with spaces |
Ins_Char(' ', COUNT, #3*2+2) // fill first line with spaces |
||
Line 5,719: | Line 5,719: | ||
Ins_Char(#21, OVERWRITE) |
Ins_Char(#21, OVERWRITE) |
||
Ins_Char('*', OVERWRITE) |
Ins_Char('*', OVERWRITE) |
||
}</ |
}</syntaxhighlight> |
||
===Recursive=== |
===Recursive=== |
||
{{trans|BASIC}} |
{{trans|BASIC}} |
||
Vedit macro language does not have recursive functions, so some pushing and popping is needed to implement recursion. |
Vedit macro language does not have recursive functions, so some pushing and popping is needed to implement recursion. |
||
< |
<syntaxhighlight lang="vedit">#1 = 1 // x |
||
#2 = 1 // y |
#2 = 1 // y |
||
#3 = 16 // length (height of the triangle / 2) |
#3 = 16 // length (height of the triangle / 2) |
||
Line 5,752: | Line 5,752: | ||
Num_Pop(1,4) |
Num_Pop(1,4) |
||
} |
} |
||
Return</ |
Return</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="ecmascript">var size = 1 << 4 |
||
for (y in size-1..0) { |
for (y in size-1..0) { |
||
System.write(" " * y) |
System.write(" " * y) |
||
for (x in 0...size-y) System.write((x&y != 0) ? " " : "* ") |
for (x in 0...size-y) System.write((x&y != 0) ? " " : "* ") |
||
System.print() |
System.print() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,785: | Line 5,785: | ||
=={{header|X86 Assembly}}== |
=={{header|X86 Assembly}}== |
||
Translation of XPL0. Assemble with tasm, tlink /t |
Translation of XPL0. Assemble with tasm, tlink /t |
||
< |
<syntaxhighlight lang="asm"> .model tiny |
||
.code |
.code |
||
.486 |
.486 |
||
Line 5,812: | Line 5,812: | ||
loop tri10 ;next I |
loop tri10 ;next I |
||
ret |
ret |
||
end start</ |
end start</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,835: | Line 5,835: | ||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">code ChOut=8, CrLf=9; |
||
def Order=4, Size=1<<Order; |
def Order=4, Size=1<<Order; |
||
int S1, S2, I; |
int S1, S2, I; |
||
Line 5,847: | Line 5,847: | ||
S2:= S2 xor S1>>1; |
S2:= S2 xor S1>>1; |
||
]; |
]; |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,871: | Line 5,871: | ||
=={{header|Yabasic}}== |
=={{header|Yabasic}}== |
||
{{trans|Phix}} |
{{trans|Phix}} |
||
< |
<syntaxhighlight lang="yabasic">sub rep$(n, c$) |
||
local i, s$ |
local i, s$ |
||
Line 5,896: | Line 5,896: | ||
sierpinski(i) |
sierpinski(i) |
||
next |
next |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="zkl">level,d := 3,T("*"); |
||
foreach n in (level + 1){ |
foreach n in (level + 1){ |
||
sp:=" "*(2).pow(n); |
sp:=" "*(2).pow(n); |
||
Line 5,906: | Line 5,906: | ||
d.apply(fcn(a){ String(a," ",a) })); |
d.apply(fcn(a){ String(a," ",a) })); |
||
} |
} |
||
d.concat("\n").println();</ |
d.concat("\n").println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
Revision as of 14:55, 28 August 2022
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Produce an ASCII representation of a Sierpinski triangle of order N.
- Example
The Sierpinski triangle of order 4 should look like this:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Related tasks
- Sierpinski triangle/Graphical for graphics images of this pattern.
- Sierpinski carpet
11l
F sierpinski(n)
V d = [String(‘*’)]
L(i) 0 .< n
V sp = ‘ ’ * (2 ^ i)
d = d.map(x -> @sp‘’x‘’@sp) [+] d.map(x -> x‘ ’x)
R d
print(sierpinski(4).join("\n"))
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8080 Assembly
argmt: equ 5Dh ; Command line argument
puts: equ 9 ; CP/M syscall to print a string
putch: equ 2 ; CP/M syscall to print a character
org 100h
mvi b,4 ; Default order is 4
mvi e,' ' ; Keep space in E since we're saving it anyway
lda argmt ; Argument given?
cmp e ; If not, use default
jz start
sui '0' ; Make sure given N makes sense
cpi 3 ; <3?
jc start
cpi 8 ; >=8?
jnc start
mov b,a
start: mvi a,1 ; Find size (2 ** order)
shift: rlc
dcr b
jnz shift
mov b,a ; B = size
mov c,a ; C = current line
line: mov d,c ; D = column
indent: mov a,e ; Indent line
call chout
dcr d
jnz indent
column: mov a,c ; line + col <= size?
add d
dcr a
cmp b
jnc cdone
mov a,c ; (line - 1) & col == 0?
dcr a
ana d
mov a,e ; space if not, star if so
jnz print
mvi a,'*'
print: call chout
mov a,e
call chout
inr d
jmp column
cdone: push b ; done, print newline
push d
lxi d,nl
mvi c,puts
call 5
pop d
pop b
dcr c ; next line
jnz line
ret
chout: push b ; save BC and DE
push d
mov e,a ; print character
mvi c,putch
call 5
pop d ; restore BC and DE
pop b
ret
nl: db 13,10,'$'
- Output:
For order 4 (default if no given):
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8086 Assembly
putch: equ 2 ; MS-DOS syscall to print character
puts: equ 9 ; MS-DOS syscall to print string
argmt: equ 5Dh ; MS-DOS still has FCB in same place as CP/M
cpu 8086
org 100h
section .text
mov cx,4 ; Default order is 4
mov al,[argmt]
sub al,'3' ; Argument is there and makes sense? (3 - 7)
cmp al,7-3
ja start ; If not, use default
add al,3 ; If so, use it
mov cl,al
start: mov bl,1 ; Let BL be the size (2 ** order)
shl bl,cl
mov bh,bl ; Let BH be the current line
line: mov cl,bh ; Let CL be the column
mov dl,' ' ; Indent line with spaces
mov ah,putch
indent: int 21h
loop indent
column: mov al,cl ; line + column <= size?
add al,bh
cmp al,bl
ja .done ; then column is done
mov al,bh ; (line - 1) & column == 0?
dec al
test al,cl
jnz .print ; space if not, star if so
mov dl,'*'
.print: int 21h
mov dl,' '
int 21h
inc cx ; next column
jmp column
.done: mov dx,nl ; done, print newline
mov ah,puts
int 21h
dec bh ; next line
jnz line
ret
nl: db 13,10,'$'
- Output:
For order 4 (default if no order given):
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ACL2
(defun pascal-row (prev)
(if (endp (rest prev))
(list 1)
(cons (+ (first prev) (second prev))
(pascal-row (rest prev)))))
(defun pascal-triangle-r (rows prev)
(if (zp rows)
nil
(let ((curr (cons 1 (pascal-row prev))))
(cons curr (pascal-triangle-r (1- rows) curr)))))
(defun pascal-triangle (rows)
(cons (list 1)
(pascal-triangle-r rows (list 1))))
(defun print-odds-row (row)
(if (endp row)
(cw "~%")
(prog2$ (cw (if (oddp (first row)) "[]" " "))
(print-odds-row (rest row)))))
(defun print-spaces (n)
(if (zp n)
nil
(prog2$ (cw " ")
(print-spaces (1- n)))))
(defun print-odds (triangle height)
(if (endp triangle)
nil
(progn$ (print-spaces height)
(print-odds-row (first triangle))
(print-odds (rest triangle) (1- height)))))
(defun print-sierpenski (levels)
(let ((height (1- (expt 2 levels))))
(print-odds (pascal-triangle height)
height)))
Action!
PROC Main()
BYTE x,y,size=[16]
Graphics(0)
PutE() PutE()
y=size-1
DO
FOR x=1 TO y+2
DO Put(' ) OD
FOR x=0 TO size-y-1
DO
IF (x&y)=0 THEN
Print("* ")
ELSE
Print(" ")
FI
OD
PutE()
IF y=0 THEN
EXIT
FI
y==-1
OD
- Output:
Screenshot from Atari 8-bit computer
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Ada
This Ada example creates a string of the binary value for each line, converting the '0' values to spaces.
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Strings.Fixed;
with Interfaces; use Interfaces;
procedure Sieteri_Triangles is
subtype Practical_Order is Unsigned_32 range 0..4;
function Pow(X : Unsigned_32; N : Unsigned_32) return Unsigned_32 is
begin
if N = 0 then
return 1;
else
return X * Pow(X, N - 1);
end if;
end Pow;
procedure Print(Item : Unsigned_32) is
use Ada.Strings.Fixed;
package Ord_Io is new Ada.Text_Io.Modular_Io(Unsigned_32);
use Ord_Io;
Temp : String(1..36) := (others => ' ');
First : Positive;
Last : Positive;
begin
Put(To => Temp, Item => Item, Base => 2);
First := Index(Temp, "#") + 1;
Last := Index(Temp(First..Temp'Last), "#") - 1;
for I in reverse First..Last loop
if Temp(I) = '0' then
Put(' ');
else
Put(Temp(I));
end if;
end loop;
New_Line;
end Print;
procedure Sierpinski (N : Practical_Order) is
Size : Unsigned_32 := Pow(2, N);
V : Unsigned_32 := Pow(2, Size);
begin
for I in 0..Size - 1 loop
Print(V);
V := Shift_Left(V, 1) xor Shift_Right(V,1);
end loop;
end Sierpinski;
begin
for N in Practical_Order loop
Sierpinski(N);
end loop;
end Sieteri_Triangles;
alternative using modular arithmetic:
with Ada.Command_Line;
with Ada.Text_IO;
procedure Main is
subtype Order is Natural range 1 .. 32;
type Mod_Int is mod 2 ** Order'Last;
procedure Sierpinski (N : Order) is
begin
for Line in Mod_Int range 0 .. 2 ** N - 1 loop
for Col in Mod_Int range 0 .. 2 ** N - 1 loop
if (Line and Col) = 0 then
Ada.Text_IO.Put ('X');
else
Ada.Text_IO.Put (' ');
end if;
end loop;
Ada.Text_IO.New_Line;
end loop;
end Sierpinski;
N : Order := 4;
begin
if Ada.Command_Line.Argument_Count = 1 then
N := Order'Value (Ada.Command_Line.Argument (1));
end if;
Sierpinski (N);
end Main;
- Output:
XXXXXXXXXXXXXXXX X X X X X X X X XX XX XX XX X X X X XXXX XXXX X X X X XX XX X X XXXXXXXX X X X X XX XX X X XXXX X X XX X
ALGOL 68
PROC sierpinski = (INT n)[]STRING: (
FLEX[0]STRING d := "*";
FOR i TO n DO
[UPB d * 2]STRING next;
STRING sp := " " * (2 ** (i-1));
FOR x TO UPB d DO
STRING dx = d[x];
next[x] := sp+dx+sp;
next[UPB d+x] := dx+" "+dx
OD;
d := next
OD;
d
);
printf(($gl$,sierpinski(4)))
ALGOL W
begin
integer SIZE;
SIZE := 16;
for y := SIZE - 1 step - 1 until 0 do begin
integer x;
for i := 0 until y - 1 do writeon( " " );
x := 0;
while x + y < SIZE do begin
writeon( if number( bitstring( x ) and bitstring( y ) ) not = 0 then " " else "* " );
x := x + 1
end while_x_plus_y_lt_SIZE ;
write();
end for_y
end.
AppleScript
Centering any previous triangle block over two adjacent duplicates:
------------------- SIERPINKSI TRIANGLE ------------------
-- sierpinski :: Int -> [String]
on sierpinski(n)
if n > 0 then
set previous to sierpinski(n - 1)
set padding to replicate(2 ^ (n - 1), space)
script alignedCentre
on |λ|(s)
concat(padding & s & padding)
end |λ|
end script
script adjacentDuplicates
on |λ|(s)
unwords(replicate(2, s))
end |λ|
end script
-- Previous triangle block centered,
-- and placed on 2 adjacent duplicates.
map(alignedCentre, previous) & map(adjacentDuplicates, previous)
else
{"*"}
end if
end sierpinski
--------------------------- TEST -------------------------
on run
unlines(sierpinski(4))
end run
-------------------- GENERIC FUNCTIONS -------------------
-- concat :: [[a]] -> [a] | [String] -> String
on concat(xs)
if length of xs > 0 and class of (item 1 of xs) is string then
set acc to ""
else
set acc to {}
end if
repeat with i from 1 to length of xs
set acc to acc & item i of xs
end repeat
acc
end concat
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if n < 1 then return out
set dbl to {a}
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
-- unlines, unwords :: [String] -> String
on unlines(xs)
intercalate(linefeed, xs)
end unlines
on unwords(xs)
intercalate(space, xs)
end unwords
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Or generating each line as an XOR / Rule 90 / Pascal triangle rewrite of the previous line.
----------- SIERPINSKI TRIANGLE BY XOR / RULE 90 ---------
-- sierpinskiTriangle :: Int -> String
on sierpinskiTriangle(intOrder)
-- A Sierpinski triangle of order N
-- is a Pascal triangle (of N^2 rows)
-- mod 2
-- pascalModTwo :: Int -> [[String]]
script pascalModTwo
on |λ|(intRows)
-- addRow [[Int]] -> [[Int]]
script addRow
-- nextRow :: [Int] -> [Int]
on nextRow(row)
-- The composition of AsciiBinary . mod two . add
-- is reduced here to a rule from
-- two parent characters above,
-- to the child character below.
-- Rule 90 also reduces to this XOR relationship
-- between left and right neighbours.
-- rule :: Character -> Character -> Character
script rule
on |λ|(a, b)
if a = b then
space
else
"*"
end if
end |λ|
end script
zipWith(rule, {" "} & row, row & {" "})
end nextRow
on |λ|(xs)
xs & {nextRow(item -1 of xs)}
end |λ|
end script
foldr(addRow, {{"*"}}, enumFromTo(1, intRows - 1))
end |λ|
end script
-- The centring foldr (fold right) below starts from the end of the list,
-- (the base of the triangle) which has zero indent.
-- Each preceding row has one more indent space than the row below it.
script centred
on |λ|(sofar, row)
set strIndent to indent of sofar
{triangle:strIndent & intercalate(space, row) & linefeed & ¬
triangle of sofar, indent:strIndent & space}
end |λ|
end script
triangle of foldr(centred, {triangle:"", indent:""}, ¬
pascalModTwo's |λ|(intOrder ^ 2))
end sierpinskiTriangle
--------------------------- TEST -------------------------
on run
set strTriangle to sierpinskiTriangle(4)
set the clipboard to strTriangle
strTriangle
end run
-------------------- GENERIC FUNCTIONS -------------------
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
if m > n then
set d to -1
else
set d to 1
end if
set lst to {}
repeat with i from m to n by d
set end of lst to i
end repeat
return lst
end enumFromTo
-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldr
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys)
end repeat
return lst
end tell
end zipWith
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Arturo
sierpinski: function [order][
s: shl 1 order
loop (s-1)..0 'y [
do.times: y -> prints " "
loop 0..dec s-y 'x [
if? zero? and x y -> prints "* "
else -> prints " "
]
print ""
]
]
sierpinski 4
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ATS
(* ****** ****** *)
//
// How to compile:
//
// patscc -DATS_MEMALLOC_LIBC -o sierpinski sierpinski.dats
//
(* ****** ****** *)
//
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
#define SIZE 16
implement
main0 () =
{
//
var x: int
//
val () =
for (x := SIZE-1; x >= 0; x := x-1)
{
var i: int
val () =
for (i := 0; i < x; i := i+1)
{
val () = print_char(' ')
}
var y: int
val () =
for (y := 0; y + x < SIZE; y := y+1)
{
val y = g0int2uint_int_uint(y)
val x = g0int2uint_int_uint(x)
val () = print_string(if (x land y) != 0 then " " else "* ")
}
val ((*flushed*)) = print_newline()
}
//
} (* end of [main0] *)
AutoHotkey
ahk discussion
Loop 6
MsgBox % Triangle(A_Index)
Triangle(n,x=0,y=1) { ; Triangle(n) -> string of dots and spaces of Sierpinski triangle
Static t, l ; put chars in a static string
If (x < 1) { ; when called with one parameter
l := 2*x := 1<<(n-1) ; - compute location, string size
VarSetCapacity(t,l*x,32) ; - allocate memory filled with spaces
Loop %x%
NumPut(13,t,A_Index*l-1,"char") ; - new lines in the end of rows
}
If (n = 1) ; at the bottom of recursion
Return t, NumPut(46,t,x-1+(y-1)*l,"char") ; - write "." (better at proportional fonts)
u := 1<<(n-2)
Triangle(n-1,x,y) ; draw smaller triangle here
Triangle(n-1,x-u,y+u) ; smaller triangle down-left
Triangle(n-1,x+u,y+u) ; smaller triangle down right
Return t
}
APL
A←67⍴0⋄A[34]←1⋄' #'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A]
AWK
# WST.AWK - Waclaw Sierpinski's triangle contributed by Dan Nielsen
# syntax: GAWK -f WST.AWK [-v X=anychar] iterations
# example: GAWK -f WST.AWK -v X=* 2
BEGIN {
n = ARGV[1] + 0 # iterations
if (n !~ /^[0-9]+$/) { exit(1) }
if (n == 0) { width = 3 }
row = split("X,X X,X X,X X X X",A,",") # seed the array
for (i=1; i<=n; i++) { # build triangle
width = length(A[row])
for (j=1; j<=row; j++) {
str = A[j]
A[j+row] = sprintf("%-*s %-*s",width,str,width,str)
}
row *= 2
}
for (j=1; j<=row; j++) { # print triangle
if (X != "") { gsub(/X/,substr(X,1,1),A[j]) }
sub(/ +$/,"",A[j])
printf("%*s%s\n",width-j+1,"",A[j])
}
exit(0)
}
BASH (feat. sed & tr)
This version completely avoids any number-theoretic workarounds. Instead, it repeatedly replaces characters by "blocks of characters". The strategy is in no way bash-specific, it would work with any other language just as well, but is particularly well suited for tools like sed and tr.
#!/bin/bash
# Basic principle:
#
#
# x -> dxd d -> dd s -> s
# xsx dd s
#
# In the end all 'd' and 's' are removed.
# 0x7F800000
function rec(){
if [ $1 == 0 ]
then
echo "x"
else
rec $[ $1 - 1 ] | while read line ; do
echo "$line" | sed "s/d/dd/g" | sed "s/x/dxd/g"
echo "$line" | sed "s/d/dd/g" | sed "s/x/xsx/g"
done
fi
}
rec $1 | tr 'dsx' ' *'
BASIC
DECLARE SUB triangle (x AS INTEGER, y AS INTEGER, length AS INTEGER, n AS INTEGER)
CLS
triangle 1, 1, 16, 5
SUB triangle (x AS INTEGER, y AS INTEGER, length AS INTEGER, n AS INTEGER)
IF n = 0 THEN
LOCATE y, x: PRINT "*";
ELSE
triangle x, y + length, length / 2, n - 1
triangle x + length, y, length / 2, n - 1
triangle x + length * 2, y + length, length / 2, n - 1
END IF
END SUB
Note: The total height of the triangle is 2 * parameter length. It should be power of two so that the pattern matches evenly with the character cells. Value 16 will thus create pattern of 32 lines.
BASIC256
clg
call triangle (1, 1, 60)
end
subroutine triangle (x, y, l)
if l = 0 then
color blue
text (x, y, "*")
else
call triangle (x, y + l, int(l/2))
call triangle (x + l, y, int(l/2))
call triangle (x + l * 2, y + l, int(l/2))
end if
end subroutine
BBC BASIC
MODE 8
OFF
order% = 5
PROCsierpinski(0, 0, 2^(order%-1))
REPEAT UNTIL GET
END
DEF PROCsierpinski(x%, y%, l%)
IF l% = 0 THEN
PRINT TAB(x%,y%) "*";
ELSE
PROCsierpinski(x%, y%+l%, l% DIV 2)
PROCsierpinski(x%+l%, y%, l% DIV 2)
PROCsierpinski(x%+l%+l%, y%+l%, l% DIV 2)
ENDIF
ENDPROC
FreeBASIC
sub sier(x as uinteger, y as uinteger, l as uinteger)
if l=0 then
locate y, x: print "*"
else
sier(x,y+l,l\2)
sier(x+l,y,l\2)
sier(x+2*l,y+l,l\2)
end if
end sub
cls
sier(1,1,2^3)
IS-BASIC
100 PROGRAM "Triangle.bas"
110 TEXT 40
120 CALL TRIANGLE(1,1,8)
130 DEF TRIANGLE(X,Y,L)
140 IF L=0 THEN
150 PRINT AT Y,X:"*"
160 ELSE
170 CALL TRIANGLE(X,Y+L,INT(L/2))
180 CALL TRIANGLE(X+L,Y,INT(L/2))
190 CALL TRIANGLE(X+2*L,Y+L,INT(L/2))
200 END IF
210 END DEF
BCPL
get "libhdr"
manifest $( SIZE = 1 << 4 $)
let start() be
$( for y = SIZE-1 to 0 by -1 do
$( for i=1 to y do wrch(' ')
for x=0 to SIZE-y-1 do
writes((x & y) ~= 0 -> " ", "** ")
wrch('*N')
$)
$)
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Befunge
This is a version of the cellular automaton (rule 90) construction. The order, N, is specified by the first number on the stack. It uses a single line of the playfield for the cell buffer, so the upper limit for N should be 5 on a standard Befunge-93 implementation. Interpreters with poor memory handling may not work with anything over 3, though, and a Befunge-98 interpreter should theoretically be unlimited.
41+2>\#*1#2-#<:#\_$:1+v
v:$_:#`0#\\#00#:p#->#1<
>2/1\0p:2/\::>1-:>#v_1v
>8#4*#*+#+,#5^#5g0:< 1
vg11<\*g11!:g 0-1:::<p<
>!*+!!\0g11p\ 0p1-:#^_v
@$$_\#!:#::#-^#1\$,+55<
Burlesque
{JPp{
-.'sgve!
J{JL[2./+.' j.*PppP.+PPj.+}m[
j{J" "j.+.+}m[
.+
}{vv{"*"}}PPie} 's sv
4 'sgve!unsh
BQN
Sierp ← {" •" ⊏˜ (⌽↕2⋆𝕩)⌽˘∾˘∾⟜0¨∧´∘∨⌜˜⥊↕2⥊˜𝕩}
- Output:
Sierp 3 ┌─ ╵" • • • • • • • • • • • • • • • • • • • • • • • • • • • " ┘
C
#include <stdio.h>
#define SIZE (1 << 4)
int main()
{
int x, y, i;
for (y = SIZE - 1; y >= 0; y--, putchar('\n')) {
for (i = 0; i < y; i++) putchar(' ');
for (x = 0; x + y < SIZE; x++)
printf((x & y) ? " " : "* ");
}
return 0;
}
Automaton
This solution uses a cellular automaton (rule 90) with a proper initial status.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#ifndef _POSIX_C_SOURCE
char *strdup(const char *s)
{
int l = strlen(s);
char *r = malloc(l+1);
memcpy(r, s, l+1);
return r;
}
#endif
#define truth(X) ((X)=='*'?true:false)
void rule_90(char *evstr)
{
int i;
int l = strlen(evstr);
bool s[3];
char *cp = strdup(evstr);
for(i=0;i < l; i++) {
s[1] = truth(cp[i]);
s[0] = (i-1) < 0 ? false : truth(cp[i-1]);
s[2] = (i+1) < l ? truth(cp[i+1]) : false;
if ( (s[0] && !s[2]) || (!s[0] && s[2]) ) {
evstr[i] = '*';
} else {
evstr[i] = ' ';
}
}
free(cp);
}
void sierpinski_triangle(int n)
{
int i;
int l = 1<<(n+1);
char *b = malloc(l+1);
memset(b, ' ', l);
b[l] = 0;
b[l>>1] = '*';
printf("%s\n", b);
for(i=0; i < l/2-1;i++) {
rule_90(b);
printf("%s\n", b);
}
free(b);
}
int main()
{
sierpinski_triangle(4);
return EXIT_SUCCESS;
}
C#
using System;
using System.Collections;
namespace RosettaCode {
class SierpinskiTriangle {
int len;
BitArray b;
public SierpinskiTriangle(int n) {
if (n < 1) {
throw new ArgumentOutOfRangeException("Order must be greater than zero");
}
len = 1 << (n+1);
b = new BitArray(len+1, false);
b[len>>1] = true;
}
public void Display() {
for (int j = 0; j < len / 2; j++) {
for (int i = 0; i < b.Count; i++) {
Console.Write("{0}", b[i] ? "*" : " ");
}
Console.WriteLine();
NextGen();
}
}
private void NextGen() {
BitArray next = new BitArray(b.Count, false);
for (int i = 0; i < b.Count; i++) {
if (b[i]) {
next[i - 1] = next[i - 1] ^ true;
next[i + 1] = next[i + 1] ^ true;
}
}
b = next;
}
}
}
namespace RosettaCode {
class Program {
static void Main(string[] args) {
SierpinskiTriangle t = new SierpinskiTriangle(4);
t.Display();
}
}
}
using static System.Console;
class Sierpinsky
{
static void Main(string[] args)
{
int order;
if(!int.TryParse(args.Length > 0 ? args[0] : "", out order)) order = 4;
int size = (1 << order);
for (int y = size - 1; y >= 0; y--, WriteLine())
{
for (int i = 0; i < y; i++) Write(' ');
for (int x = 0; x + y < size; x++)
Write((x & y) != 0 ? " " : "* ");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public static List<String> Sierpinski(int n)
{
var lines = new List<string> { "*" };
string space = " ";
for (int i = 0; i < n; i++)
{
lines = lines.Select(x => space + x + space)
.Concat(lines.Select(x => x + " " + x)).ToList();
space += space;
}
return lines;
}
static void Main(string[] args)
{
foreach (string s in Sierpinski(4))
Console.WriteLine(s);
}
}
Or, with fold / reduce (a.k.a. aggregate):
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static List<string> Sierpinski(int n)
{
return Enumerable.Range(0, n).Aggregate(
new List<string>(){"*"},
(p, i) => {
string SPACE = " ".PadRight((int)Math.Pow(2, i));
var temp = new List<string>(from x in p select SPACE + x + SPACE);
temp.AddRange(from x in p select x + " " + x);
return temp;
}
);
}
static void Main ()
{
foreach(string s in Sierpinski(4)) { Console.WriteLine(s); }
}
}
C++
A STL-centric recursive solution that uses the new lambda functions in C++11.
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
template<typename OutIt>
void sierpinski(int n, OutIt result)
{
if( n == 0 )
{
*result++ = "*";
}
else
{
list<string> prev;
sierpinski(n-1, back_inserter(prev));
string sp(1 << (n-1), ' ');
result = transform(prev.begin(), prev.end(),
result,
[sp](const string& x) { return sp + x + sp; });
transform(prev.begin(), prev.end(),
result,
[sp](const string& x) { return x + " " + x; });
}
}
int main()
{
sierpinski(4, ostream_iterator<string>(cout, "\n"));
return 0;
}
Clojure
With a touch of Clojure's sequence handling.
(ns example
(:require [clojure.contrib.math :as math]))
; Length of integer in binary
; (copied from a private multimethod in clojure.contrib.math)
(defmulti #^{:private true} integer-length class)
(defmethod integer-length java.lang.Integer [n]
(count (Integer/toBinaryString n)))
(defmethod integer-length java.lang.Long [n]
(count (Long/toBinaryString n)))
(defmethod integer-length java.math.BigInteger [n]
(count (.toString n 2)))
(defn sierpinski-triangle [order]
(loop [size (math/expt 2 order)
v (math/expt 2 (- size 1))]
(when (pos? size)
(println
(apply str (map #(if (bit-test v %) "*" " ")
(range (integer-length v)))))
(recur
(dec size)
(bit-xor (bit-shift-left v 1) (bit-shift-right v 1))))))
(sierpinski-triangle 4)
CLU
sierpinski = proc (size: int) returns (string)
ss: stream := stream$create_output()
for i: int in int$from_to(0, size*4-1) do
c: int := 1
for j: int in int$from_to(1, size*4-1-i) do
stream$putc(ss, ' ')
end
for k: int in int$from_to(0, i) do
if c//2=0 then
stream$puts(ss, " ")
else
stream$puts(ss, " *")
end
c := c*(i-k)/(k+1)
end
stream$putc(ss, '\n')
end
return(stream$get_contents(ss))
end sierpinski
start_up = proc ()
stream$puts(
stream$primary_output(),
sierpinski(4)
)
end start_up
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
COBOL
and retains a more Fortran-like coding style than is really idiomatic in COBOL.
identification division.
program-id. sierpinski-triangle-program.
data division.
working-storage section.
01 sierpinski.
05 n pic 99.
05 i pic 999.
05 k pic 999.
05 m pic 999.
05 c pic 9(18).
05 i-limit pic 999.
05 q pic 9(18).
05 r pic 9.
procedure division.
control-paragraph.
move 4 to n.
multiply n by 4 giving i-limit.
subtract 1 from i-limit.
perform sierpinski-paragraph
varying i from 0 by 1 until i is greater than i-limit.
stop run.
sierpinski-paragraph.
subtract i from i-limit giving m.
multiply m by 2 giving m.
perform m times,
display space with no advancing,
end-perform.
move 1 to c.
perform inner-loop-paragraph
varying k from 0 by 1 until k is greater than i.
display ''.
inner-loop-paragraph.
divide c by 2 giving q remainder r.
if r is equal to zero then display ' * ' with no advancing.
if r is not equal to zero then display ' ' with no advancing.
compute c = c * (i - k) / (k + 1).
Comal
0010 DIM part$(FALSE:TRUE) OF 2
0020 part$(FALSE):=" ";part$(TRUE):="* "
0030 INPUT "Order? ":order#
0040 size#:=2^order#
0050 FOR y#:=size#-1 TO 0 STEP -1 DO
0060 PRINT " "*y#,
0070 FOR x#:=0 TO size#-y#-1 DO PRINT part$(x# BITAND y#=0),
0080 PRINT
0090 ENDFOR y#
0100 END
- Output:
Order? 4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Common Lisp
(defun print-sierpinski (order)
(loop with size = (expt 2 order)
repeat size
for v = (expt 2 (1- size)) then (logxor (ash v -1) (ash v 1))
do (fresh-line)
(loop for i below (integer-length v)
do (princ (if (logbitp i v) "*" " ")))))
Printing each row could also be done by printing the integer in base 2 and replacing zeroes with spaces: (princ (substitute #\Space #\0 (format nil "~%~2,vR" (1- (* 2 size)) v)))
Replacing the iteration with for v = 1 then (logxor v (ash v 1)) produces a "right" triangle instead of an "equilateral" one.
Alternate approach:
(defun sierpinski (n)
(if (= n 0) '("*")
(nconc (mapcar (lambda (e) (format nil "~A~A~0@*~A" (make-string (expt 2 (1- n)) :initial-element #\ ) e)) (sierpinski (1- n)))
(mapcar (lambda (e) (format nil "~A ~A" e e)) (sierpinski (1- n))))))
(mapc #'print (sierpinski 4))
Cowgol
include "cowgol.coh";
include "argv.coh";
var order: uint8 := 4; # default order
# Read order from command line if there is an argument
ArgvInit();
var argmt := ArgvNext();
if argmt != 0 as [uint8] then
var a: int32;
(a, argmt) := AToI(argmt);
if a<3 or 7<a then
print("Order must be between 3 and 7.");
print_nl();
ExitWithError();
end if;
order := a as uint8;
end if;
var one: uint8 := 1; # shift argument can't be constant...
var size: uint8 := one << order;
var y: uint8 := size;
while y > 0 loop
var x: uint8 := 0;
while x < y-1 loop
print_char(' ');
x := x + 1;
end loop;
x := 0;
while x + y <= size loop
if x & (y-1) != 0 then
print(" ");
else
print("* ");
end if;
x := x + 1;
end loop;
print_nl();
y := y - 1;
end loop;
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
D
Run-time Version
void main() /*@safe*/ {
import std.stdio, std.algorithm, std.string, std.array;
enum level = 4;
auto d = ["*"];
foreach (immutable n; 0 .. level) {
immutable sp = " ".replicate(2 ^^ n);
d = d.map!(a => sp ~ a ~ sp).array ~
d.map!(a => a ~ " " ~ a).array;
}
d.join('\n').writeln;
}
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Compile-time Version
Same output.
import std.string, std.range, std.algorithm;
string sierpinski(int level) pure nothrow /*@safe*/ {
auto d = ["*"];
foreach (immutable i; 0 .. level) {
immutable sp = " ".replicate(2 ^^ i);
d = d.map!(a => sp ~ a ~ sp).array ~
d.map!(a => a ~ " " ~ a).array;
}
return d.join('\n');
}
pragma(msg, 4.sierpinski);
void main() {}
Simple Version
Same output.
void showSierpinskiTriangle(in uint order) nothrow @safe @nogc {
import core.stdc.stdio: putchar;
foreach_reverse (immutable y; 0 .. 2 ^^ order) {
foreach (immutable _; 0 .. y)
' '.putchar;
foreach (immutable x; 0 .. 2 ^^ order - y) {
putchar((x & y) ? ' ' : '*');
' '.putchar;
}
'\n'.putchar;
}
}
void main() nothrow @safe @nogc {
4.showSierpinskiTriangle;
}
Alternative Version
This uses a different algorithm and shows a different output.
import core.stdc.stdio: putchar;
import std.algorithm: swap;
void showSierpinskiTriangle(in uint nLevels) nothrow @safe
in {
assert(nLevels > 0);
} body {
alias Row = bool[];
static void applyRules(in Row r1, Row r2) pure nothrow @safe @nogc {
r2[0] = r1[0] || r1[1];
r2[$ - 1] = r1[$ - 2] || r1[$ - 1];
foreach (immutable i; 1 .. r2.length - 1)
r2[i] = r1[i - 1] != r1[i] || r1[i] != r1[i + 1];
}
static void showRow(in Row r) nothrow @safe @nogc {
foreach (immutable b; r)
putchar(b ? '#' : ' ');
'\n'.putchar;
}
immutable width = 2 ^^ (nLevels + 1) - 1;
auto row1 = new Row(width);
auto row2 = new Row(width);
row1[width / 2] = true;
foreach (immutable _; 0 .. 2 ^^ nLevels) {
showRow(row1);
applyRules(row1, row2);
row1.swap(row2);
}
}
void main() @safe nothrow {
foreach (immutable i; 1 .. 6) {
i.showSierpinskiTriangle;
'\n'.putchar;
}
}
- Output:
# ### # ### ## ## ####### # ### ## ## ####### ## ## #### #### ## ## ## ## ############### # ### ## ## ####### ## ## #### #### ## ## ## ## ############### ## ## #### #### ## ## ## ## ######## ######## ## ## ## ## #### #### #### #### ## ## ## ## ## ## ## ## ############################### # ### ## ## ####### ## ## #### #### ## ## ## ## ############### ## ## #### #### ## ## ## ## ######## ######## ## ## ## ## #### #### #### #### ## ## ## ## ## ## ## ## ############################### ## ## #### #### ## ## ## ## ######## ######## ## ## ## ## #### #### #### #### ## ## ## ## ## ## ## ## ################ ################ ## ## ## ## #### #### #### #### ## ## ## ## ## ## ## ## ######## ######## ######## ######## ## ## ## ## ## ## ## ## #### #### #### #### #### #### #### #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###############################################################
Delphi
program SierpinskiTriangle;
{$APPTYPE CONSOLE}
procedure PrintSierpinski(order: Integer);
var
x, y, size: Integer;
begin
size := (1 shl order) - 1;
for y := size downto 0 do
begin
Write(StringOfChar(' ', y));
for x := 0 to size - y do
begin
if (x and y) = 0 then
Write('* ')
else
Write(' ');
end;
Writeln;
end;
end;
begin
PrintSierpinski(4);
end.
Draco
word SIZE = 1 << 4;
proc nonrec main() void:
unsigned SIZE x, y;
for y from SIZE-1 downto 0 do
for x from 1 upto y do write(' ') od;
for x from 0 upto SIZE - y - 1 do
write(if x & y ~= 0 then " " else "* " fi)
od;
writeln()
od
corp
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
DWScript
procedure PrintSierpinski(order : Integer);
var
x, y, size : Integer;
begin
size := (1 shl order)-1;
for y:=size downto 0 do begin
Print(StringOfChar(' ', y));
for x:=0 to size-y do begin
if (x and y)=0 then
Print('* ')
else Print(' ');
end;
PrintLn('');
end;
end;
PrintSierpinski(4);
E
def printSierpinski(order, out) {
def size := 2**order
for y in (0..!size).descending() {
out.print(" " * y)
for x in 0..!(size-y) {
out.print((x & y).isZero().pick("* ", " "))
}
out.println()
}
}
? printSierpinski(4, stdout)
Non-ASCII version (quality of results will depend greatly on text renderer):
def printSierpinski(order, out) {
def size := 2**order
for y in (0..!size).descending() {
out.print(" " * y)
for x in 0..!(size-y) {
out.print((x & y).isZero().pick("◢◣", " "))
}
out.println()
}
}
Elixir
defmodule RC do
def sierpinski_triangle(n) do
f = fn(x) -> IO.puts "#{x}" end
Enum.each(triangle(n, ["*"], " "), f)
end
defp triangle(0, down, _), do: down
defp triangle(n, down, sp) do
newDown = (for x <- down, do: sp<>x<>sp) ++ (for x <- down, do: x<>" "<>x)
triangle(n-1, newDown, sp<>sp)
end
end
RC.sierpinski_triangle(4)
Elm
import String exposing (..)
import Html exposing (..)
import Html.Attributes as A exposing (..)
import Html.Events exposing (..)
import Html.App exposing (beginnerProgram)
import Result exposing (..)
sierpinski : Int -> List String
sierpinski n =
let down n = sierpinski (n - 1)
space n = repeat (2 ^ (n - 1)) " "
in case n of
0 -> ["*"]
_ -> List.map ((\st -> space n ++ st) << (\st -> st ++ space n)) (down n)
++ List.map (join " " << List.repeat 2) (down n)
main = beginnerProgram { model = "4", view = view, update = update }
update newStr oldStr = newStr
view : String -> Html String
view levelString =
div []
([ Html.form
[]
[ label [ myStyle ] [ text "Level: "]
, input
[ placeholder "triangle level."
, value levelString
, on "input" targetValue
, type' "number"
, A.min "0"
, myStyle
]
[]
]
] ++
[ pre [] (levelString
|> toInt
|> withDefault 0
|> sierpinski
|> List.map (\s -> div [] [text s]))
])
myStyle : Attribute msg
myStyle =
style
[ ("height", "20px")
, ("padding", "5px 0 0 5px")
, ("font-size", "1em")
, ("text-align", "left")
]
Link to live demo: http://dc25.github.io/sierpinskiElm/
Erlang
-module(sierpinski).
-export([triangle/1]).
triangle(N) ->
F = fun(X) -> io:format("~s~n",[X]) end,
lists:foreach(F, triangle(N, ["*"], " ")).
triangle(0, Down, _) -> Down;
triangle(N, Down, Sp) ->
NewDown = [Sp++X++Sp || X<-Down]++[X++" "++X || X <- Down],
triangle(N-1, NewDown, Sp++Sp).
Euphoria
procedure triangle(integer x, integer y, integer len, integer n)
if n = 0 then
position(y,x) puts(1,'*')
else
triangle (x, y+len, floor(len/2), n-1)
triangle (x+len, y, floor(len/2), n-1)
triangle (x+len*2, y+len, floor(len/2), n-1)
end if
end procedure
clear_screen()
triangle(1,1,8,4)
Excel
LAMBDA
Binding the names sierpinskiTriangle, sierpCentered and sierpDoubled to the following lambda expressions in the Name Manager of the Excel WorkBook:
(See LAMBDA: The ultimate Excel worksheet function)
sierpinskiTriangle
=LAMBDA(c,
LAMBDA(n,
IF(0 = n,
c,
LET(
prev, sierpinskiTriangle(c)(n - 1),
APPENDROWS(
sierpCentered(prev)
)(
sierpDoubled(prev)
)
)
)
)
)
sierpCentered
=LAMBDA(grid,
LET(
nRows, ROWS(grid),
padding, IF(
SEQUENCE(nRows, nRows, 1, 1),
" "
),
APPENDCOLS(
APPENDCOLS(padding)(grid)
)(padding)
)
)
sierpDoubled
=LAMBDA(grid,
APPENDCOLS(
APPENDCOLS(grid)(
IF(SEQUENCE(ROWS(grid), 1, 1, 1),
" "
)
)
)(grid)
)
and also assuming the following generic bindings in the Name Manager for the WorkBook:
APPENDCOLS
=LAMBDA(xs,
LAMBDA(ys,
LET(
nx, COLUMNS(xs),
colIndexes, SEQUENCE(1, nx + COLUMNS(ys)),
rowIndexes, SEQUENCE(MAX(ROWS(xs), ROWS(ys))),
IFERROR(
IF(nx < colIndexes,
INDEX(ys, rowIndexes, colIndexes - nx),
INDEX(xs, rowIndexes, colIndexes)
),
NA()
)
)
)
)
APPENDROWS
=LAMBDA(xs,
LAMBDA(ys,
LET(
nx, ROWS(xs),
rowIndexes, SEQUENCE(nx + ROWS(ys)),
colIndexes, SEQUENCE(
1,
MAX(COLUMNS(xs), COLUMNS(ys))
),
IFERROR(
IF(rowIndexes <= nx,
INDEX(xs, rowIndexes, colIndexes),
INDEX(ys, rowIndexes - nx, colIndexes)
),
NA()
)
)
)
)
gridString
=LAMBDA(grid,
LET(
ixCol, SEQUENCE(ROWS(grid), 1, 1, 1),
CHAR(10) & CONCAT(
APPENDCOLS(
IF(ixCol, " ")
)(
APPENDCOLS(grid)(
IF(ixCol, CHAR(10))
)
)
)
)
)
- Output:
As grids:
(Each formula in the B column (adjacent to an integer in the A column) defines an array which populates a whole grid (for example the range B12:P19) with a Sierpinski triangle).
fx | =sierpinskiTriangle("▲")(A2) | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | ||
1 | |||||||||||||||||
2 | 0 | ▲ | |||||||||||||||
3 | |||||||||||||||||
4 | 1 | ▲ | |||||||||||||||
5 | ▲ | ▲ | |||||||||||||||
6 | |||||||||||||||||
7 | 2 | ▲ | |||||||||||||||
8 | ▲ | ▲ | |||||||||||||||
9 | ▲ | ▲ | |||||||||||||||
10 | ▲ | ▲ | ▲ | ▲ | |||||||||||||
11 | |||||||||||||||||
12 | 3 | ▲ | |||||||||||||||
13 | ▲ | ▲ | |||||||||||||||
14 | ▲ | ▲ | |||||||||||||||
15 | ▲ | ▲ | ▲ | ▲ | |||||||||||||
16 | ▲ | ▲ | |||||||||||||||
17 | ▲ | ▲ | ▲ | ▲ | |||||||||||||
18 | ▲ | ▲ | ▲ | ▲ | |||||||||||||
19 | ▲ | ▲ | ▲ | ▲ | ▲ | ▲ | ▲ | ▲ |
or as strings, using a monospaced font, and the wrap text alignment setting in Excel:
fx | =gridString(sierpinskiTriangle("*")(A2)) | ||
---|---|---|---|
A | B | ||
1 | Iterations | Sierpinski Triangle | |
2 | 0 |
* | |
3 | 1 |
* * * | |
4 | 2 |
* * * * * * * * * | |
5 | 3 |
* * * * * * * * * * * * * * * * * * * * * * * * * * * | |
6 | 4 |
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
F#
let sierpinski n =
let rec loop down space n =
if n = 0 then
down
else
loop (List.map (fun x -> space + x + space) down @
List.map (fun x -> x + " " + x) down)
(space + space)
(n - 1)
in loop ["*"] " " n
let () =
List.iter (fun (i:string) -> System.Console.WriteLine(i)) (sierpinski 4)
Factor
USING: io kernel math sequences ;
IN: sierpinski
: iterate-triangle ( triange spaces -- triangle' )
[ [ dup surround ] curry map ]
[ drop [ dup " " glue ] map ] 2bi append ;
: (sierpinski) ( triangle spaces n -- triangle' )
dup 0 = [ 2drop "\n" join ] [
[
[ iterate-triangle ]
[ nip dup append ] 2bi
] dip 1 - (sierpinski)
] if ;
: sierpinski ( n -- )
[ { "*" } " " ] dip (sierpinski) print ;
FALSE
[[$][$1&["*"]?$~1&[" "]?2/]#%"
"]s: { stars }
[$@$@|@@&~&]x: { xor }
[1\[$][1-\2*\]#%]e: { 2^n }
[e;!1\[$][\$s;!$2*x;!\1-]#%%]t:
4t;!
FOCAL
01.10 A "ORDER",O;S S=2^(O+1)
01.20 F X=0,S;S L(X)=0
01.30 S L(S/2)=1
01.40 F I=1,S/2;D 2;D 3
01.90 Q
02.10 F X=1,S-1;D 2.3
02.20 T !;R
02.30 I (L(X)),2.4,2.5
02.40 T " "
02.50 T "*"
03.10 F X=0,S;S K(X)=FABS(L(X-1)-L(X+1))
03.20 F X=0,S;S L(X)=K(X)
- Output:
ORDER:4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Forth
: stars ( mask -- )
begin
dup 1 and if [char] * else bl then emit
1 rshift dup
while space repeat drop ;
: triangle ( order -- )
1 swap lshift ( 2^order )
1 over 0 do
cr over i - spaces dup stars
dup 2* xor
loop 2drop ;
5 triangle
Fortran
This method calculates a Pascal's triangle and replaces every odd number with a * and every even number with a space. The limitation of this approach is the size of the numbers in the Pascal's triangle. Tryng to print an order 8 Sierpinski's triangle will overflow a 32 bit integer and an order 16 will overflow a 64 bit integer.
program Sierpinski_triangle
implicit none
call Triangle(4)
contains
subroutine Triangle(n)
implicit none
integer, parameter :: i64 = selected_int_kind(18)
integer, intent(in) :: n
integer :: i, k
integer(i64) :: c
do i = 0, n*4-1
c = 1
write(*, "(a)", advance="no") repeat(" ", 2 * (n*4 - 1 - i))
do k = 0, i
if(mod(c, 2) == 0) then
write(*, "(a)", advance="no") " "
else
write(*, "(a)", advance="no") " * "
end if
c = c * (i - k) / (k + 1)
end do
write(*,*)
end do
end subroutine Triangle
end program Sierpinski_triangle
GAP
# Using parity of binomial coefficients
SierpinskiTriangle := function(n)
local i, j, s, b;
n := 2^n - 1;
b := " ";
while Size(b) < n do
b := Concatenation(b, b);
od;
for i in [0 .. n] do
s := "";
for j in [0 .. i] do
if IsEvenInt(Binomial(i, j)) then
Append(s, " ");
else
Append(s, "* ");
fi;
od;
Print(b{[1 .. n - i]}, s, "\n");
od;
end;
SierpinskiTriangle(4);
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
gnuplot
Making and printing a text string, using bit-twiddling to decide whether each character should be a space or a star.
# Return a string space or star to print at x,y.
# Must have x<y. x<0 is the left side of the triangle.
# If x<-y then it's before the left edge and the return is a space.
char(x,y) = (y+x>=0 && ((y+x)%2)==0 && ((y+x)&(y-x))==0 ? "*" : " ")
# Return a string which is row y of the triangle from character
# position x through to the right hand end x==y, inclusive.
row(x,y) = (x<=y ? char(x,y).row(x+1,y) : "\n")
# Return a string of stars, spaces and newlines which is the
# Sierpinski triangle from row y to limit, inclusive.
# The first row is y=0.
triangle(y,limit) = (y <= limit ? row(-limit,y).triangle(y+1,limit) : "")
# Print rows 0 to 15, which is the order 4 triangle per the task.
print triangle(0,15)
Go
"Δ" (Greek capital letter delta) looks good for grain, as does Unicode triangle, "△". ASCII "." and "^" are pleasing. "/\\", "´`", and "◢◣"" make interesting wide triangles.
package main
import (
"fmt"
"strings"
"unicode/utf8"
)
var order = 4
var grain = "*"
func main() {
t := []string{grain + strings.Repeat(" ", utf8.RuneCountInString(grain))}
for ; order > 0; order-- {
sp := strings.Repeat(" ", utf8.RuneCountInString(t[0])/2)
top := make([]string, len(t))
for i, s := range t {
top[i] = sp + s + sp
t[i] += s
}
t = append(top, t...)
}
for _, r := range t {
fmt.Println(r)
}
}
Golfscript
Cambia el "3" a un número mayor para un triángulo más grande.
' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n*
- Output:
/\ /__\ /\ /\ /__\/__\ /\ /\ /__\ /__\ /\ /\ /\ /\ /__\/__\/__\/__\ /\ /\ /__\ /__\ /\ /\ /\ /\ /__\/__\ /__\/__\ /\ /\ /\ /\ /__\ /__\ /__\ /__\ /\ /\ /\ /\ /\ /\ /\ /\ /__\/__\/__\/__\/__\/__\/__\/__\
Groovy
Solution:
def stPoints;
stPoints = { order, base=[0,0] ->
def right = [base[0], base[1]+2**order]
def up = [base[0]+2**(order-1), base[1]+2**(order-1)]
(order == 0) \
? [base]
: (stPoints(order-1, base) + stPoints(order-1, right) + stPoints(order-1, up))
}
def stGrid = { order ->
def h = 2**order
def w = 2**(order+1) - 1
def grid = (0..<h).collect { (0..<w).collect { ' ' } }
stPoints(order).each { grid[it[0]][it[1]] = (order%10).toString() }
grid
}
Test:
stGrid(0).reverse().each { println it.sum() }
println()
stGrid(1).reverse().each { println it.sum() }
println()
stGrid(2).reverse().each { println it.sum() }
println()
stGrid(3).reverse().each { println it.sum() }
println()
stGrid(4).reverse().each { println it.sum() }
println()
stGrid(5).reverse().each { println it.sum() }
println()
stGrid(6).reverse().each { println it.sum() }
- Output:
0 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
Haskell
sierpinski 0 = ["*"]
sierpinski n = map ((space ++) . (++ space)) down ++
map (unwords . replicate 2) down
where down = sierpinski (n - 1)
space = replicate (2 ^ (n - 1)) ' '
main = mapM_ putStrLn $ sierpinski 4
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
We can see how the approach above (centering a preceding block over two duplicates) generates a framing rectangle at each stage, by making the right padding (plus the extra space between duplicates) more distinct and visible:
import Data.List (intercalate)
sierpinski :: Int -> [String]
sierpinski 0 = ["▲"]
sierpinski n =
[ flip
intercalate
([replicate (2 ^ (n - 1))] <*> " -"),
(<>) <*> ('+' :)
]
>>= (<$> sierpinski (n - 1))
main :: IO ()
main = mapM_ putStrLn $ sierpinski 4
- Output:
▲--------------- ▲+▲-------------- ▲-+ ▲------------- ▲+▲+▲+▲------------ ▲---+ ▲----------- ▲+▲--+ ▲+▲---------- ▲-+ ▲-+ ▲-+ ▲--------- ▲+▲+▲+▲+▲+▲+▲+▲-------- ▲-------+ ▲------- ▲+▲------+ ▲+▲------ ▲-+ ▲-----+ ▲-+ ▲----- ▲+▲+▲+▲----+ ▲+▲+▲+▲---- ▲---+ ▲---+ ▲---+ ▲--- ▲+▲--+ ▲+▲--+ ▲+▲--+ ▲+▲-- ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲- ▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲
Using bitwise and between x and y coords:
import Data.Bits ((.&.))
sierpinski n = map row [m, m-1 .. 0] where
m = 2^n - 1
row y = replicate y ' ' ++ concatMap cell [0..m - y] where
cell x | y .&. x == 0 = " *"
| otherwise = " "
main = mapM_ putStrLn $ sierpinski 4
import Data.List (intersperse)
-- Top down, each row after the first is an XOR / Rule90 rewrite.
-- Bottom up, each line above the base is indented 1 more space.
sierpinski :: Int -> String
sierpinski = fst . foldr spacing ([], []) . rule90 . (2 ^)
where
rule90 = scanl next "*" . enumFromTo 1 . subtract 1
where
next =
const
. ( (zipWith xor . (' ' :))
<*> (<> " ")
)
xor l r
| l == r = ' '
| otherwise = '*'
spacing x (s, w) =
( concat
[w, intersperse ' ' x, "\n", s],
w <> " "
)
main :: IO ()
main = putStr $ sierpinski 4
Or simply as a right fold:
sierpinski :: Int -> [String]
sierpinski n =
foldr
( \i xs ->
let s = replicate (2 ^ i) ' '
in fmap ((s <>) . (<> s)) xs
<> fmap
( (<>)
<*> (' ' :)
)
xs
)
["*"]
[n - 1, n - 2 .. 0]
main :: IO ()
main = (putStrLn . unlines . sierpinski) 4
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Haxe
class Main
{
static function main()
{
triangle(3);
}
static inline var SPACE = ' ';
static inline var STAR = '*';
static function triangle(o) {
var n = 1 << o;
var line = new Array<String>();
for (i in 0...(n*2)) line[i] = SPACE;
line[n] = '*';
for (i in 0...n) {
Sys.println(line.join(''));
var u ='*';
var start = n - i;
var end = n + i + 1;
var t = SPACE;
for (j in start...end) {
t = (line[j-1] == line[j+1] ? SPACE : STAR);
line[j-1] = u;
u = t;
}
line[n+i] = t;
line[n+i+1] = STAR;
}
}
}
Hoon
|= n=@ud
=+ m=0
=+ o=(reap 1 '*')
|^ ?: =(m n) o
$(m +(m), o (weld top bot))
++ gap (fil 3 (pow 2 m) ' ')
++ top (turn o |=(l=@t (rap 3 gap l gap ~)))
++ bot (turn o |=(l=@t (rap 3 l ' ' l ~)))
--
Icon and Unicon
This is a text based adaption of a program from the IPL and Icon Graphics book. The triangle is presented with a twist. Based on an idea from "Chaos and Fractals" by Peitgen, Jurgens, and Saupe.
Adapted from graphics/sier1.icn
- Sample output for order 3:
Triangle order = 2 * * * * * * * * * * * * * * * * * * * * * * * * * * *
IDL
The only 'special' thing here is that the math is done in a byte array, filled with the numbers 32 and 42 and then output through a "string(array)" which prints the ascii representation of each individual element in the array.
pro sierp,n
s = (t = bytarr(3+2^(n+1))+32b)
t[2^n+1] = 42b
for lines = 1,2^n do begin
print,string( (s = t) )
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b
end
end
J
There are any number of succinct ways to produce this in J. Here's one that exploits self-similarity:
|. _31]\ ,(,.~ , ])^:4 ,: '* '
Here, (,.~ , ])^:4 ,: '* ' is the basic structure (with 4 iterations) and the rest of it is just formatting.
Here's one that leverages the relationship between Sierpinski's and Pascal's triangles:
' *' {~ '1' = (- |."_1 [: ": 2 | !/~) i._16
Here, !/~ i._16 gives us pascal's triangle (and we want a power of 2 (or, for the formatting we are using here a negative of a power of 2) for the size of the square in which contains the triangle, and (2 + |/~) i._16 is a boolean representation where the 1s correspond to odd values in pascal's triangle, and the rest is just formatting.
(Aside: it's popular to say that booleans are not integers, but this is a false representation of George Boole's work.)
Java
Replace translations. Recursive solution.
public class SierpinskiTriangle {
public static void main(String[] args) {
System.out.println(getSierpinskiTriangle(4));
}
private static final String getSierpinskiTriangle(int n) {
if ( n == 0 ) {
return "*";
}
String s = getSierpinskiTriangle(n-1);
String [] split = s.split("\n");
int length = split.length;
// Top triangle
StringBuilder sb = new StringBuilder();
String top = buildSpace((int)Math.pow(2, n-1));
for ( int i = 0 ; i < length ;i++ ) {
sb.append(top);
sb.append(split[i]);
sb.append("\n");
}
// Two triangles side by side
for ( int i = 0 ; i < length ;i++ ) {
sb.append(split[i]);
sb.append(buildSpace(length-i));
sb.append(split[i]);
sb.append("\n");
}
return sb.toString();
}
private static String buildSpace(int n) {
StringBuilder sb = new StringBuilder();
while ( n > 0 ) {
sb.append(" ");
n--;
}
return sb.toString();
}
}
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
JavaFX Script
function sierpinski(n : Integer) {
var down = ["*"];
var space = " ";
for (i in [1..n]) {
down = [for (x in down) "{space}{x}{space}", for (x in down) "{x} {x}"];
space = "{space}{space}";
}
for (x in down) {
println("{x}")
}
}
sierpinski(4);
JavaScript
ES5
Functional
Using a functional idiom of JavaScript, we can construct a Sierpinksi triangle as a Pascal triangle (mod 2), mapping the binary pattern to centred strings.
(function (order) {
// Sierpinski triangle of order N constructed as
// Pascal triangle of 2^N rows mod 2
// with 1 encoded as "▲"
// and 0 encoded as " "
function sierpinski(intOrder) {
return function asciiPascalMod2(intRows) {
return range(1, intRows - 1)
.reduce(function (lstRows) {
var lstPrevRow = lstRows.slice(-1)[0];
// Each new row is a function of the previous row
return lstRows.concat([zipWith(function (left, right) {
// The composition ( asciiBinary . mod 2 . add )
// reduces to a rule from 2 parent characters
// to a single child character
// Rule 90 also reduces to the same XOR
// relationship between left and right neighbours
return left === right ? " " : "▲";
}, [' '].concat(lstPrevRow), lstPrevRow.concat(' '))]);
}, [
["▲"] // Tip of triangle
]);
}(Math.pow(2, intOrder))
// As centred lines, from bottom (0 indent) up (indent below + 1)
.reduceRight(function (sofar, lstLine) {
return {
triangle: sofar.indent + lstLine.join(" ") + "\n" +
sofar.triangle,
indent: sofar.indent + " "
};
}, {
triangle: "",
indent: ""
}).triangle;
};
var zipWith = function (f, xs, ys) {
return xs.length === ys.length ? xs
.map(function (x, i) {
return f(x, ys[i]);
}) : undefined;
},
range = function (m, n) {
return Array.apply(null, Array(n - m + 1))
.map(function (x, i) {
return m + i;
});
};
// TEST
return sierpinski(order);
})(4);
Output (N=4)
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
Imperative
function triangle(o) {
var n = 1 << o,
line = new Array(2 * n),
i, j, t, u;
for (i = 0; i < line.length; ++i) line[i] = ' ';
line[n] = '*';
for (i = 0; i < n; ++i) {
document.write(line.join('') + "\n");
u = '*';
for (j = n - i; j < n + i + 1; ++j) {
t = (line[j - 1] == line[j + 1] ? ' ' : '*');
line[j - 1] = u;
u = t;
}
line[n + i] = t;
line[n + i + 1] = '*';
}
}
document.write("<pre>\n");
triangle(6);
document.write("</pre>");
ES6
Directly in terms of the built-in Array methods .map, .reduce, and .from, and without much abstraction, possibly at the cost of some legibility:
(() => {
"use strict";
// --------------- SIERPINSKI TRIANGLE ---------------
// sierpinski :: Int -> String
const sierpinski = n =>
Array.from({
length: n
})
.reduce(
(xs, _, i) => {
const s = " ".repeat(2 ** i);
return [
...xs.map(x => s + x + s),
...xs.map(x => `${x} ${x}`)
];
},
["*"]
)
.join("\n");
// ---------------------- TEST -----------------------
return sierpinski(4);
})();
Centering any preceding triangle block over two adjacent duplicates:
(() => {
"use strict";
// ----- LINES OF SIERPINSKI TRIANGLE AT LEVEL N -----
// sierpinski :: Int -> [String]
const sierpTriangle = n =>
// Previous triangle centered with
// left and right padding,
0 < n ? (
ap([
map(
xs => ap([
compose(
ks => ks.join(""),
replicate(2 ** (n - 1))
)
])([" ", "-"])
.join(xs)
),
// above a pair of duplicates,
// placed one character apart.
map(s => `${s}+${s}`)
])([sierpTriangle(n - 1)])
.flat()
) : ["▲"];
// ---------------------- TEST -----------------------
const main = () =>
sierpTriangle(4)
.join("\n");
// ---------------- GENERIC FUNCTIONS ----------------
// ap (<*>) :: [(a -> b)] -> [a] -> [b]
const ap = fs =>
// The sequential application of each of a list
// of functions to each of a list of values.
// apList([x => 2 * x, x => 20 + x])([1, 2, 3])
// -> [2, 4, 6, 21, 22, 23]
xs => fs.flatMap(f => xs.map(f));
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
// map :: (a -> b) -> [a] -> [b]
const map = f => xs => xs.map(f);
// replicate :: Int -> a -> [a]
const replicate = n =>
// A list of n copies of x.
x => Array.from({
length: n
}, () => x);
// ---------------------- TEST -----------------------
return main();
})();
- Output:
▲--------------- ▲+▲-------------- ▲-+ ▲------------- ▲+▲+▲+▲------------ ▲---+ ▲----------- ▲+▲--+ ▲+▲---------- ▲-+ ▲-+ ▲-+ ▲--------- ▲+▲+▲+▲+▲+▲+▲+▲-------- ▲-------+ ▲------- ▲+▲------+ ▲+▲------ ▲-+ ▲-----+ ▲-+ ▲----- ▲+▲+▲+▲----+ ▲+▲+▲+▲---- ▲---+ ▲---+ ▲---+ ▲--- ▲+▲--+ ▲+▲--+ ▲+▲--+ ▲+▲-- ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲- ▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲
Or constructed as 2^N lines of Pascal's triangle mod 2, and mapped to centred {1:asterisk, 0:space} strings.
(() => {
"use strict";
// --------------- SIERPINSKI TRIANGLE ---------------
// sierpinski :: Int -> [Bool]
const sierpinski = intOrder =>
// Reduce/folding from the last item (base of list)
// which has zero left indent.
// Each preceding row has one more indent space
// than the row beneath it.
pascalMod2Chars(2 ** intOrder)
.reduceRight((a, x) => ([
`${a[1]}${x.join(" ")}\n${a[0]}`,
`${a[1]} `
]), ["", ""])[0];
// pascalMod2Chars :: Int -> [[Char]]
const pascalMod2Chars = nRows =>
enumFromTo(1)(nRows - 1)
.reduce(sofar => {
const rows = sofar.slice(-1)[0];
// Rule 90 also reduces to the same XOR
// relationship between left and right neighbours.
return ([
...sofar,
zipWith(
l => r => l === r ? (
" "
) : "*"
)([" ", ...rows])([...rows, " "])
]);
}, [
["*"]
]);
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
sierpinski(4);
// --------------------- GENERIC ---------------------
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
// A list constructed by zipping with a
// custom function, rather than with the
// default tuple constructor.
xs => ys => xs.map(
(x, i) => f(x)(ys[i])
).slice(
0, Math.min(xs.length, ys.length)
);
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
// MAIN ---
return main();
})();
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
jq
Works with gojq, the Go implementation of jq
Preliminaries
def elementwise(f):
transpose | map(f) ;
# input: an array of decimal numbers
def bitwise_and:
# Input: an integer
# Output: a stream of 0s and 1s
def stream:
recurse(if . > 0 then ./2|floor else empty end) | . % 2 ;
# Input: a 0-1 array
def toi:
reduce .[] as $c ( {power:1 , ans: 0};
.ans += ($c * .power) | .power *= 2 )
| .ans;
if any(.==0) then 0
else map([stream])
| (map(length) | min) as $min
| map( .[:$min] ) | elementwise(min) | toi
end;
def sierpinski:
pow(2; .) as $size
| range($size-1; -1; -1) as $y
| reduce range(0; $size - $y) as $x ( (" " * $y);
. + (if ([$x,$y]|bitwise_and) == 0 then "* " else " " end));
4 | sierpinski
- Output:
As elsewhere.
Julia
function sierpinski(n, token::AbstractString="*")
x = fill(token, 1, 1)
for _ in 1:n
h, w = size(x)
s = fill(" ", h,(w + 1) ÷ 2)
t = fill(" ", h,1)
x = [[s x s] ; [x t x]]
end
return x
end
function printsierpinski(m::Matrix)
for r in 1:size(m, 1)
println(join(m[r, :]))
end
end
sierpinski(4) |> printsierpinski
Kotlin
// version 1.1.2
const val ORDER = 4
const val SIZE = 1 shl ORDER
fun main(args: Array<String>) {
for (y in SIZE - 1 downTo 0) {
for (i in 0 until y) print(" ")
for (x in 0 until SIZE - y) print(if ((x and y) != 0) " " else "* ")
println()
}
}
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Liberty BASIC
nOrder=4
call triangle 1, 1, nOrder
end
SUB triangle x, y, n
IF n = 0 THEN
LOCATE x,y: PRINT "*";
ELSE
n=n-1
length=2^n
call triangle x, y+length, n
call triangle x+length, y, n
call triangle x+length*2, y+length, n
END IF
END SUB
Logo
; Print rows of the triangle from 0 to :limit inclusive.
; limit=15 gives the order 4 form per the task.
; The range of :y is arbitrary, any rows of the triangle can be printed.
make "limit 15
for [y 0 :limit] [
for [x -:limit :y] [
type ifelse (and :y+:x >= 0 ; blank left of triangle
(remainder :y+:x 2) = 0 ; only "even" squares
(bitand :y+:x :y-:x) = 0 ; Sierpinski bit test
) ["*] ["| |] ; star or space
]
print []
]
Lua
Ported from the list-comprehension Python version.
function sierpinski(depth)
lines = {}
lines[1] = '*'
for i = 2, depth+1 do
sp = string.rep(' ', 2^(i-2))
tmp = {}
for idx, line in ipairs(lines) do
tmp[idx] = sp .. line .. sp
tmp[idx+#lines] = line .. ' ' .. line
end
lines = tmp
end
return table.concat(lines, '\n')
end
print(sierpinski(4))
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Maple
S := proc(n)
local i, j, values, position;
values := [ seq(" ",i=1..2^n-1), "*" ];
printf("%s\n",cat(op(values)));
for i from 2 to 2^n do
position := [ ListTools:-SearchAll( "*", values ) ];
values := Array([ seq(0, i=1..2^n+i-1) ]);
for j to numelems(position) do
values[position[j]-1] := values[position[j]-1] + 1;
values[position[j]+1] := values[position[j]+1] + 1;
end do;
values := subs( { 2 = " ", 0 = " ", 1 = "*"}, values );
printf("%s\n",cat(op(convert(values, list))));
end do:
end proc:
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Mathematica /Wolfram Language
Cellular automaton (rule 90) based solution:
n=4;Grid[CellularAutomaton[90,{{1},0},2^n-1]/.{0->" ",1->"*"},ItemSize->All]
Using built-in function:
SierpinskiMesh[3]
MATLAB
STRING was introduced in version R2016b.
n = 4;
d = string('*');
for k = 0 : n - 1
sp = repelem(' ', 2 ^ k);
d = [sp + d + sp, d + ' ' + d];
end
disp(d.join(char(10)))
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Cellular Automaton Version
n = 2 ^ 4 - 1;
tr = + ~(-n : n);
for k = 1:n
tr(k + 1, :) = bitget(90, 1 + filter2([4 2 1], tr(k, :)));
end
char(10 * tr + 32)
Mixed Version
spy(mod(abs(pascal(32,1)),2)==1)
NetRexx
/* NetRexx */
options replace format comments java crossref symbols nobinary
numeric digits 1000
runSample(arg)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) public static
BLACK_UPPOINTING_TRIANGLE = '\u25b2'
parse arg ordr filr .
if ordr = '' | ordr = '.' then ordr = 4
if filr = '' | filr = '.' then filler = BLACK_UPPOINTING_TRIANGLE
else filler = filr
drawSierpinskiTriangle(ordr, filler)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method drawSierpinskiTriangle(ordr, filler = Rexx '^') public static
n = 1 * (2 ** ordr)
line = ' '.copies(2 * n)
line = line.overlay(filler, n + 1) -- set the top point of the triangle
loop row = 1 to n -- NetRexx arrays, lists etc. index from 1
say line.strip('t')
u = filler
loop col = 2 + n - row to n + row
cl = line.substr(col - 1, 1)
cr = line.substr(col + 1, 1)
if cl == cr then t = ' '
else t = filler
line = line.overlay(u, col - 1)
u = t
end col
j2 = n + row - 1
j3 = n + row
line = line.overlay(t, j2 + 1)
line = line.overlay(filler, j3 + 1)
end row
return
- Output:
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
Nim
const size = 1 shl 4 - 1
for y in countdown(size, 0):
for i in 0 .. <y:
stdout.write " "
for x in 0 .. size-y:
if (x and y) != 0:
stdout.write " "
else:
stdout.write "* "
stdout.write "\n"
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
OCaml
let sierpinski n =
let rec loop down space n =
if n = 0 then
down
else
loop (List.map (fun x -> space ^ x ^ space) down @
List.map (fun x -> x ^ " " ^ x) down)
(space ^ space)
(n - 1)
in loop ["*"] " " n
let () =
List.iter print_endline (sierpinski 4)
Oforth
This solution uses a cellular automaton (rule 90 for triangle).
automat(rule, n) runs cellular automaton for rule "rule" for n generations.
: nextGen(l, r)
| i |
StringBuffer new
l size loop: i [
l at(i 1 -) '*' == 4 *
l at(i) '*' == 2 * +
l at(i 1 +) '*' == +
2 swap pow r bitAnd ifTrue: [ '*' ] else: [ ' ' ] over addChar
] ;
: automat(rule, n)
StringBuffer new " " <<n(n) "*" over + +
#[ dup println rule nextGen ] times(n) drop ;
: sierpinskiTriangle(n)
90 4 n * automat ;
- Output:
>4 sierpinskiTriangle * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ok >
Oz
declare
fun {NextTriangle Triangle}
Sp = {Spaces {Length Triangle}}
in
{Flatten
[{Map Triangle fun {$ X} Sp#X#Sp end}
{Map Triangle fun {$ X} X#" "#X end}
]}
end
fun {Spaces N} if N == 0 then nil else & |{Spaces N-1} end end
fun lazy {Iterate F X}
X|{Iterate F {F X}}
end
SierpinskiTriangles = {Iterate NextTriangle ["*"]}
in
{ForAll {Nth SierpinskiTriangles 5} System.showInfo}
PARI/GP
Sierpinski(n)={
my(s=2^n-1);
forstep(y=s,0,-1,
for(i=1,y,print1(" "));
for(x=0,s-y,
print1(if(bitand(x,y)," ","*"))
);
print()
)
};
Sierpinski(4)
- Output:
* ** * * **** * * ** ** * * * * ******** * * ** ** * * * * **** **** * * * * ** ** ** ** * * * * * * * * ****************
Pascal
program Sierpinski;
function ipow(b, n : Integer) : Integer;
var
i : Integer;
begin
ipow := 1;
for i := 1 to n do
ipow := ipow * b
end;
function truth(a : Char) : Boolean;
begin
if a = '*' then
truth := true
else
truth := false
end;
function rule_90(ev : String) : String;
var
l, i : Integer;
cp : String;
s : Array[0..1] of Boolean;
begin
l := length(ev);
cp := copy(ev, 1, l);
for i := 1 to l do begin
if (i-1) < 1 then
s[0] := false
else
s[0] := truth(ev[i-1]);
if (i+1) > l then
s[1] := false
else
s[1] := truth(ev[i+1]);
if ( (s[0] and not s[1]) or (s[1] and not s[0]) ) then
cp[i] := '*'
else
cp[i] := ' ';
end;
rule_90 := cp
end;
procedure triangle(n : Integer);
var
i, l : Integer;
b : String;
begin
l := ipow(2, n+1);
b := ' ';
for i := 1 to l do
b := concat(b, ' ');
b[round(l/2)] := '*';
writeln(b);
for i := 1 to (round(l/2)-1) do begin
b := rule_90(b);
writeln(b)
end
end;
begin
triangle(4)
end.
Perl
version 1
sub sierpinski {
my ($n) = @_;
my @down = '*';
my $space = ' ';
foreach (1..$n) {
@down = (map("$space$_$space", @down), map("$_ $_", @down));
$space = "$space$space";
}
return @down;
}
print "$_\n" foreach sierpinski 4;
one-liner
perl -le '$l=40;$l2="!" x $l;substr+($l2^=$l2),$l/2,1,"\xFF";for(1..16){local $_=$l2;y/\0\xFF/ */;print;($lf,$rt)=map{substr $l2 x 2,$_%$l,$l;}1,-1;$l2=$lf^$rt;select undef,undef,undef,.1;}'
Phix
procedure sierpinski(integer n) integer lim = power(2,n)-1 for y=lim to 0 by -1 do puts(1,repeat(' ',y)) for x=0 to lim-y do puts(1,iff(and_bits(x,y)?" ":"* ")) end for puts(1,"\n") end for end procedure for i=1 to 5 do sierpinski(i) end for
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Phixmonti
def sierpinski
2 swap power 1 - var lim
lim 0 -1 3 tolist for
var y
32 y 1 + repeat print
0 lim y - 2 tolist for
y bitand if 32 32 chain else "* " endif print
endfor
nl
endfor
enddef
5 for
sierpinski
endfor
PHP
<?php
function sierpinskiTriangle($order) {
$char = '#';
$n = 1 << $order;
$line = array();
for ($i = 0 ; $i <= 2 * $n ; $i++) {
$line[$i] = ' ';
}
$line[$n] = $char;
for ($i = 0 ; $i < $n ; $i++) {
echo implode('', $line), PHP_EOL;
$u = $char;
for ($j = $n - $i ; $j < $n + $i + 1 ; $j++) {
$t = ($line[$j - 1] == $line[$j + 1] ? ' ' : $char);
$line[$j - 1] = $u;
$u = $t;
}
$line[$n + $i] = $t;
$line[$n + $i + 1] = $char;
}
}
sierpinskiTriangle(4);
- Output:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
Picat
go =>
foreach(N in 1..4)
sierpinski(N),
nl
end,
nl.
sierpinski(N) =>
Size = 2**N,
foreach(Y in Size-1..-1..0)
printf("%s", [' ' : _I in 1..Y]),
foreach(X in 0..Size-Y-1)
printf("%s ", cond(X /\ Y == 0, "*", " "))
end,
nl
end.
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
PicoLisp
(de sierpinski (N)
(let (D '("*") S " ")
(do N
(setq
D (conc
(mapcar '((X) (pack S X S)) D)
(mapcar '((X) (pack X " " X)) D) )
S (pack S S) ) )
D ) )
(mapc prinl (sierpinski 4))
PL/I
sierpinski: procedure options (main); /* 2010-03-30 */
declare t (79,79) char (1);
declare (i, j, k) fixed binary;
declare (y, xs, ys, xll, xrr, ixrr, limit) fixed binary;
t = ' ';
xs = 40; ys = 1;
/* Make initial triangle */
call make_triangle (xs, ys);
y = ys + 4;
xll = xs-4; xrr = xs+4;
do k = 1 to 3;
limit = 0;
do forever;
ixrr = xrr;
do i = xll to xll+limit by 8;
if t(y-1, i) = ' ' then
do;
call make_triangle (i, y);
if t(y+3,i-5) = '*' then
t(y+3,i-4), t(y+3,ixrr+4) = '*';
call make_triangle (ixrr, y);
end;
ixrr = ixrr - 8;
end;
xll = xll - 4; xrr = xrr + 4;
y = y + 4;
limit = limit + 8;
if xll+limit > xs-1 then leave;
end;
t(y-1,xs) = '*';
end;
/* Finished generation; now print the Sierpinski triangle. */
put edit (t) (skip, (hbound(t,2)) a);
make_triangle: procedure (x, y);
declare (x, y) fixed binary;
declare i fixed binary;
do i = 0 to 3;
t(y+i, x-i), t(y+i, x+i) = '*';
end;
do i = x-2 to x+2; /* The base of the triangle. */
t(y+3, i) = '*';
end;
end make_triangle;
end sierpinski;
PL/M
100H:
DECLARE ORDER LITERALLY '4';
/* CP/M BDOS CALL */
BDOS: PROCEDURE (FN, ARG);
DECLARE FN BYTE, ARG ADDRESS;
GO TO 5;
END BDOS;
PUT$CHAR: PROCEDURE (CHAR);
DECLARE CHAR BYTE;
CALL BDOS(2, CHAR);
END PUT$CHAR;
/* PRINT SIERPINSKI TRIANGLE */
DECLARE (X, Y, SIZE) BYTE;
SIZE = SHL(1, ORDER);
Y = SIZE - 1;
DO WHILE Y <> -1;
DO X = 0 TO Y;
CALL PUT$CHAR(' ');
END;
DO X = 0 TO SIZE-Y-1;
IF (X AND Y) = 0
THEN CALL PUT$CHAR('*');
ELSE CALL PUT$CHAR(' ');
CALL PUT$CHAR(' ');
END;
Y = Y - 1;
CALL PUT$CHAR(13);
CALL PUT$CHAR(10);
END;
CALL BDOS(0,0);
EOF
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Pop11
Solution using line buffer in an integer array oline, 0 represents ' ' (space), 1 represents '*' (star).
define triangle(n);
lvars k = 2**n, j, l, oline, nline;
initv(2*k+3) -> oline;
initv(2*k+3) -> nline;
for l from 1 to 2*k+3 do 0 -> oline(l) ; endfor;
1 -> oline(k+2);
0 -> nline(1);
0 -> nline(2*k+3);
for j from 1 to k do
for l from 1 to 2*k+3 do
printf(if oline(l) = 0 then ' ' else '*' endif);
endfor;
printf('\n');
for l from 2 to 2*k+2 do
(oline(l-1) + oline(l+1)) rem 2 -> nline(l);
endfor;
(oline, nline) -> (nline, oline);
endfor;
enddefine;
triangle(4);
Alternative solution, keeping all triangle as list of strings
define triangle2(n);
lvars acc = ['*'], spaces = ' ', j;
for j from 1 to n do
maplist(acc, procedure(x); spaces >< x >< spaces ; endprocedure)
<> maplist(acc, procedure(x); x >< ' ' >< x ; endprocedure) -> acc;
spaces >< spaces -> spaces;
endfor;
applist(acc, procedure(x); printf(x, '%p\n'); endprocedure);
enddefine;
triangle2(4);
PostScript
This draws the triangles in a string-rewrite fashion, where all edges form a single polyline. 9 page document showing progession.
%!PS-Adobe-3.0
%%BoundingBox 0 0 300 300
/F { 1 0 rlineto } def
/+ { 120 rotate } def
/- {-120 rotate } def
/v {.5 .5 scale } def
/^ { 2 2 scale } def
/!0{ dup 1 sub dup -1 eq not } def
/X { !0 { v X + F - X - F + X ^ } { F } ifelse pop } def
0 1 8 { 300 300 scale 0 1 12 div moveto
X + F + F fill showpage } for
%%EOF
PowerShell
function triangle($o) {
$n = [Math]::Pow(2, $o)
$line = ,' '*(2*$n+1)
$line[$n] = '█'
$OFS = ''
for ($i = 0; $i -lt $n; $i++) {
Write-Host $line
$u = '█'
for ($j = $n - $i; $j -lt $n + $i + 1; $j++) {
if ($line[$j-1] -eq $line[$j+1]) {
$t = ' '
} else {
$t = '█'
}
$line[$j-1] = $u
$u = $t
}
$line[$n+$i] = $t
$line[$n+$i+1] = '█'
}
}
Processing
Characters in drawing canvas version
void setup() {
size(410, 230);
background(255);
fill(0);
sTriangle (10, 25, 100, 5);
}
void sTriangle(int x, int y, int l, int n) {
if( n == 0) text("*", x, y);
else {
sTriangle(x, y+l, l/2, n-1);
sTriangle(x+l, y, l/2, n-1);
sTriangle(x+l*2, y+l, l/2, n-1);
}
}
Text in console version
void setup() {
print(getSierpinskiTriangle(3));
}
String getSierpinskiTriangle(int n) {
if ( n == 0 ) {
return "*";
}
String s = getSierpinskiTriangle(n-1);
String [] split = s.split("\n");
int length = split.length;
// Top triangle
String ns = "";
String top = buildSpace((int)pow(2, n-1));
for ( int i = 0; i < length; i++ ) {
ns += top;
ns += split[i];
ns += "\n";
}
// Two triangles side by side
for ( int i = 0; i < length; i++ ) {
ns += split[i];
ns += buildSpace(length-i);
ns += split[i];
ns += "\n";
}
return ns.toString();
}
String buildSpace(int n) {
String ns = "";
while ( n > 0 ) {
ns += " ";
n--;
}
return ns;
}
Prolog
Works with SWI-Prolog;
sierpinski_triangle(N) :-
Len is 2 ** (N+1) - 1,
length(L, Len),
numlist(1, Len, LN),
maplist(init(N), L, LN),
atomic_list_concat(L, Line),
writeln(Line),
NbTours is 2**N - 1,
loop(NbTours, LN, Len, L).
init(N, Cell, Num) :-
( Num is 2 ** N + 1 -> Cell = *; Cell = ' ').
loop(0, _, _, _) :- !.
loop(N, LN, Len, L) :-
maplist(compute_next_line(Len, L), LN, L1),
atomic_list_concat(L1, Line),
writeln(Line),
N1 is N - 1,
loop(N1, LN, Len, L1).
compute_next_line(Len, L, I, V) :-
I1 is I - 1,
I2 is I+1,
( I = 1 -> V0 = ' '; nth1(I1, L, V0)),
nth1(I, L, V1),
( I = Len -> V2 = ' '; nth1(I2, L, V2)),
rule_90(V0, V1, V2, V).
rule_90('*','*','*', ' ').
rule_90('*','*',' ', '*').
rule_90('*',' ','*', ' ').
rule_90('*',' ',' ', '*').
rule_90(' ','*','*', '*').
rule_90(' ','*',' ', ' ').
rule_90(' ',' ','*', '*').
rule_90(' ',' ',' ', ' ').
- Output:
?- sierpinski_triangle(4). * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * true
PureBasic
Procedure Triangle (X,Y, Length, N)
If N = 0
DrawText( Y,X, "*",#Blue)
Else
Triangle (X+Length, Y, Length/2, N-1)
Triangle (X, Y+Length, Length/2, N-1)
Triangle (X+Length, Y+Length*2, Length/2, N-1)
EndIf
EndProcedure
OpenWindow(0, 100, 100,700,500 ,"Sierpinski triangle", #PB_Window_SystemMenu |1)
StartDrawing(WindowOutput(0))
DrawingMode(#PB_2DDrawing_Transparent )
Triangle(10,10,120,5)
StopDrawing()
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
End
Python
def sierpinski(n):
d = ["*"]
for i in xrange(n):
sp = " " * (2 ** i)
d = [sp+x+sp for x in d] + [x+" "+x for x in d]
return d
print "\n".join(sierpinski(4))
Or, using fold / reduce
import functools
def sierpinski(n):
def aggregate(TRIANGLE, I):
SPACE = " " * (2 ** I)
return [SPACE+X+SPACE for X in TRIANGLE] + [X+" "+X for X in TRIANGLE]
return functools.reduce(aggregate, range(n), ["*"])
print("\n".join(sierpinski(4)))
and fold/reduce, wrapped as concatMap, can provide the list comprehensions too:
'''Sierpinski triangle'''
from functools import reduce
from operator import add
# sierpinski :: Int -> String
def sierpinski(n):
'''Nth iteration of a Sierpinksi triangle.'''
def go(xs, i):
s = ' ' * (2 ** i)
return concatMap(lambda x: [s + x + s])(xs) + (
concatMap(lambda x: [x + ' ' + x])(xs)
)
return '\n'.join(reduce(go, range(n), '*'))
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list or string over which a function f
has been mapped.
The list monad can be derived by using an (a -> [b])
function which wraps its output in a list (using an
empty list to represent computational failure).
'''
return lambda xs: (
reduce(add, map(f, xs), [])
)
print(sierpinski(4))
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Use Python's long integer and bit operator to make an infinite triangle:
x = 1
while True:
print(bin(x)[2:].replace('0', ' '))
x ^= x<<1
Quackery
[ [ dup 1 &
iff char * else space
emit
1 >> dup while
sp again ]
drop ] is stars ( mask --> )
[ bit
1 over times
[ cr over i^ - times sp
dup stars
dup 1 << ^ ]
2drop ] is triangle ( order --> )
4 triangle
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
R
Based on C# but using some of R's functionality to abbreviate code where possible.
sierpinski.triangle = function(n) {
len <- 2^(n+1)
b <- c(rep(FALSE,len/2),TRUE,rep(FALSE,len/2))
for (i in 1:(len/2))
{
cat(paste(ifelse(b,"*"," "),collapse=""),"\n")
n <- rep(FALSE,len+1)
n[which(b)-1]<-TRUE
n[which(b)+1]<-xor(n[which(b)+1],TRUE)
b <- n
}
}
sierpinski.triangle(5)
Shortened to a function of one line.
sierpinski.triangle = function(n) {
c(paste(ifelse(b<<- c(rep(FALSE,2^(n+1)/2),TRUE,rep(FALSE,2^(n+1)/2)),"*"," "),collapse=""),replicate(2^n-1,paste(ifelse(b<<-xor(c(FALSE,b[1:2^(n+1)]),c(b[2:(2^(n+1)+1)],FALSE)),"*"," "),collapse="")))
}
cat(sierpinski.triangle(5),sep="\n")
Racket
#lang racket
(define (sierpinski n)
(if (zero? n)
'("*")
(let ([spaces (make-string (expt 2 (sub1 n)) #\space)]
[prev (sierpinski (sub1 n))])
(append (map (λ(x) (~a spaces x spaces)) prev)
(map (λ(x) (~a x " " x)) prev)))))
(for-each displayln (sierpinski 5))
Raku
(formerly Perl 6)
sub sierpinski ($n) {
my @down = '*';
my $space = ' ';
for ^$n {
@down = |("$space$_$space" for @down), |("$_ $_" for @down);
$space x= 2;
}
return @down;
}
.say for sierpinski 4;
REXX
/*REXX program constructs and displays a Sierpinski triangle of up to around order 10k.*/
parse arg n mark . /*get the order of Sierpinski triangle.*/
if n=='' | n=="," then n=4 /*Not specified? Then use the default.*/
if mark=='' then mark= "*" /*MARK was specified as a character. */
if length(mark)==2 then mark=x2c(mark) /* " " " in hexadecimal. */
if length(mark)==3 then mark=d2c(mark) /* " " " " decimal. */
numeric digits 12000 /*this should handle the biggy numbers.*/
/* [↓] the blood-'n-guts of the pgm. */
do j=0 for n*4; !=1; z=left('', n*4 -1-j) /*indent the line to be displayed. */
do k=0 for j+1 /*construct the line with J+1 parts. */
if !//2==0 then z=z' ' /*it's either a blank, or ··· */
else z=z mark /* ··· it's one of 'em thar characters.*/
!=! * (j-k) % (k+1) /*calculate handy-dandy thing-a-ma-jig.*/
end /*k*/ /* [↑] finished constructing a line. */
say z /*display a line of the triangle. */
end /*j*/ /* [↑] finished showing triangle. */
/*stick a fork in it, we're all done. */
output when using the default input of order: 4
(Shown at three quarter size.)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
output when using the input of: 8 1e
(Shown at half size.)
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
output when using the input of: 32 db
(Shown at one tenth size.)
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
Output with an input of 64 can be viewed at: Sierpinski triangle/REXX output 64
Ring
# Project : Sierpinski triangle
norder=4
xy = list(40)
for i = 1 to 40
xy[i] = " "
next
triangle(1, 1, norder)
for i = 1 to 36
see xy[i] + nl
next
func triangle(x, y, n)
if n = 0
xy[y] = left(xy[y],x-1) + "*" + substr(xy[y],x+1)
else
n=n-1
length=pow(2,n)
triangle(x, y+length, n)
triangle(x+length, y, n)
triangle(x+length*2, y+length, n)
ok
Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Ruby
From the command line:
ruby -le'16.times{|y|print" "*(15-y),*(0..y).map{|x|~y&x>0?" ":" *"}}'
or,
def sierpinski_triangle(n)
triangle = ["*"]
n.times do |i|
sp = " " * (2**i)
triangle = triangle.collect {|x| sp + x + sp} +
triangle.collect {|x| x + " " + x}
end
triangle
end
puts sierpinski_triangle(4)
Using fold / reduce (aka. inject):
def sierpinski_triangle(n)
(0...n).inject(["*"]) {|triangle, i|
space = " " * (2**i)
triangle.map {|x| space + x + space} + triangle.map {|x| x + " " + x}
}
end
puts sierpinski_triangle(4)
Run BASIC
nOrder=4
dim xy$(40)
for i = 1 to 40
xy$(i) = " "
next i
call triangle 1, 1, nOrder
for i = 1 to 36
print xy$(i)
next i
end
SUB triangle x, y, n
IF n = 0 THEN
xy$(y) = left$(xy$(y),x-1) + "*" + mid$(xy$(y),x+1)
ELSE
n=n-1
length=2^n
call triangle x, y+length, n
call triangle x+length, y, n
call triangle x+length*2, y+length, n
END IF
END SUB
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Rust
use std::iter::repeat;
fn sierpinski(order: usize) {
let mut triangle = vec!["*".to_string()];
for i in 0..order {
let space = repeat(' ').take(2_usize.pow(i as u32)).collect::<String>();
// save original state
let mut d = triangle.clone();
// extend existing lines
d.iter_mut().for_each(|r| {
let new_row = format!("{}{}{}", space, r, space);
*r = new_row;
});
// add new lines
triangle.iter().for_each(|r| {
let new_row = format!("{}{}{}", r, " ", r);
d.push(new_row);
});
triangle = d;
}
triangle.iter().for_each(|r| println!("{}", r));
}
fn main() {
let order = std::env::args()
.nth(1)
.unwrap_or_else(|| "4".to_string())
.parse::<usize>()
.unwrap();
sierpinski(order);
}
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Scala
The Ruby command-line version (on Windows):
scala -e "for(y<-0 to 15){println(\" \"*(15-y)++(0 to y).map(x=>if((~y&x)>0)\" \"else\" *\")mkString)}"
The Forth version:
def sierpinski(n: Int) {
def star(n: Long) = if ((n & 1L) == 1L) "*" else " "
def stars(n: Long): String = if (n == 0L) "" else star(n) + " " + stars(n >> 1)
def spaces(n: Int) = " " * n
((1 << n) - 1 to 0 by -1).foldLeft(1L) {
case (bitmap, remainingLines) =>
println(spaces(remainingLines) + stars(bitmap))
(bitmap << 1) ^ bitmap
}
}
The Haskell version:
def printSierpinski(n: Int) {
def sierpinski(n: Int): List[String] = {
lazy val down = sierpinski(n - 1)
lazy val space = " " * (1 << (n - 1))
n match {
case 0 => List("*")
case _ => (down map (space + _ + space)) :::
(down map (List.fill(2)(_) mkString " "))
}
}
sierpinski(n) foreach println
}
Scheme
(define (sierpinski n)
(for-each
(lambda (x) (display (list->string x)) (newline))
(let loop ((acc (list (list #\*))) (spaces (list #\ )) (n n))
(if (zero? n)
acc
(loop
(append
(map (lambda (x) (append spaces x spaces)) acc)
(map (lambda (x) (append x (list #\ ) x)) acc))
(append spaces spaces)
(- n 1))))))
Seed7
$ include "seed7_05.s7i";
const func array string: sierpinski (in integer: n) is func
result
var array string: parts is 1 times "*";
local
var integer: i is 0;
var string: space is " ";
var array string: parts2 is 0 times "";
var string: x is "";
begin
for i range 1 to n do
parts2 := 0 times "";
for x range parts do
parts2 &:= [] (space & x & space);
end for;
for x range parts do
parts2 &:= [] (x & " " & x);
end for;
parts := parts2;
space &:= space;
end for;
end func;
const proc: main is func
begin
writeln(join(sierpinski(4), "\n"));
end func;
Sidef
func sierpinski_triangle(n) {
var triangle = ['*']
{ |i|
var sp = (' ' * 2**i)
triangle = (triangle.map {|x| sp + x + sp} +
triangle.map {|x| x + ' ' + x})
} * n
triangle.join("\n")
}
say sierpinski_triangle(4)
Swift
import Foundation
// Easy get/set of charAt
extension String {
subscript(index:Int) -> String {
get {
var array = Array(self)
var charAtIndex = array[index]
return String(charAtIndex)
}
set(newValue) {
var asChar = Character(newValue)
var array = Array(self)
array[index] = asChar
self = String(array)
}
}
}
func triangle(var n:Int) {
n = 1 << n
var line = ""
var t = ""
var u = ""
for (var i = 0; i <= 2 * n; i++) {
line += " "
}
line[n] = "*"
for (var i = 0; i < n; i++) {
println(line)
u = "*"
for (var j = n - i; j < n + i + 1; j++) {
t = line[j-1] == line[j + 1] ? " " : "*"
line[j - 1] = u
u = t
}
line[n + i] = t
line[n + i + 1] = "*"
}
}
Tcl
package require Tcl 8.5
proc map {lambda list} {
foreach elem $list {
lappend result [apply $lambda $elem]
}
return $result
}
proc sierpinski_triangle n {
set down [list *]
set space " "
for {set i 1} {$i <= $n} {incr i} {
set down [concat \
[map [subst -nocommands {x {expr {"$space[set x]$space"}}}] $down] \
[map {x {expr {"$x $x"}}} $down] \
]
append space $space
}
return [join $down \n]
}
puts [sierpinski_triangle 4]
TI-83 BASIC
Uses Wolfram Rule 90.
PROGRAM:SIRPNSKI
:ClrHome
:Output(1,8,"^")
:{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0}→L1
:{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}→L2
:L2→L3
:For(X,2,8,1)
:For(Y,2,17,1)
:If L1(Y-1)
:Then
:4→N
:End
:If L1(Y)
:Then
:N+2→N
:End
:If L1(Y+1)
:Then
:N+1→N
:End
:If N=1 or N=3 or N=4 or N=6
:Then
:1→L2(Y)
:Output(X,Y-1,"^")
:End
:0→N
:End
:L2→L1
:L3→L2
:End
uBasic/4tH
Input "Triangle order: ";n
n = 2^n
For y = n - 1 To 0 Step -1
For i = 0 To y
Print " ";
Next
x = 0
For x = 0 Step 1 While ((x + y) < n)
If AND (x,y) Then
Print " ";
Else
Print "* ";
EndIf
Next
Print
Next
End
Unlambda
```ci``s``s`ks``s`k`s``s`kc``s``s``si`kr`k. `k.*k
`k``s``s``s``s`s`k`s``s`ksk`k``s``si`kk`k``s`kkk
`k``s`k`s``si`kk``s`kk``s``s``s``si`kk`k`s`k`s``s`ksk`k`s`k`s`k`si``si`k`ki
`k``s`k`s``si`k`ki``s`kk``s``s``s``si`kk`k`s`k`s`k`si`k`s`k`s``s`ksk``si`k`ki
`k`ki``s`k`s`k`si``s`kkk
This produces an infinite, left-justified triangle:
* ** * * **** * * ** ** * * * * ******** * * ** ** * * * * **** **** * * * * ** ** ** ** * * * * * * * * **************** * * ** ** * * * * **** **** * * * * ** ** ** ** * * * * * * * * ******** ******** * * * * ** ** ** ** * * * * * * * * **** **** **** **** * * * * * * * * ** ** ** ** ** ** ** ** * * * * * * * * * * * * * * * * ******************************** * * ** ** * * * * ........
Ursala
the straightforward recursive solution
#import nat
triangle = ~&a^?\<<&>>! ^|RNSiDlrTSPxSxNiCK9xSx4NiCSplrTSPT/~& predecessor
the cheeky cellular automaton solution
#import std
#import nat
rule = -$<0,&,0,0,&,0,0,0>@rSS zipp0*ziD iota8
evolve "n" = @iNC ~&x+ rep"n" ^C\~& @h rule*+ swin3+ :/0+ --<0>
sierpinski = iota; --<&>@NS; iota; ^H/evolve@z @NS ^T/~& :/&
an example of each (converting from booleans to characters)
#show+
examples = mat0 ~&?(`*!,` !)*** <sierpinski3,triangle4>
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
VBA
Sub sierpinski(n As Integer)
Dim lim As Integer: lim = 2 ^ n - 1
For y = lim To 0 Step -1
Debug.Print String$(y, " ")
For x = 0 To lim - y
Debug.Print IIf(x And y, " ", "# ");
Next
Debug.Print
Next y
End Sub
Public Sub main()
Dim i As Integer
For i = 1 To 5
sierpinski i
Next i
End Sub
- Output:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
VBScript
Sub triangle(o)
n = 2 ^ o
Dim line()
ReDim line(2*n)
line(n) = "*"
i = 0
Do While i < n
WScript.StdOut.WriteLine Join(line,"")
u = "*"
j = n - i
Do While j < (n+i+1)
If line(j-1) = line(j+1) Then
t = " "
Else
t = "*"
End If
line(j-1) = u
u = t
j = j + 1
Loop
line(n+i) = t
line(n+i+1) = "*"
i = i + 1
Loop
End Sub
triangle(4)
Vedit macro language
Iterative
The macro writes the fractal into an edit buffer where it can be viewed and saved to file if required. This allows creating images larger than screen, the size is only limited by free disk space.
#3 = 16 // size (height) of the triangle
Buf_Switch(Buf_Free) // Open a new buffer for output
Ins_Char(' ', COUNT, #3*2+2) // fill first line with spaces
Ins_Newline
Line(-1) Goto_Col(#3)
Ins_Char('*', OVERWRITE) // the top of triangle
for (#10=0; #10 < #3-1; #10++) {
BOL Reg_Copy(9,1) Reg_Ins(9) // duplicate the line
#20 = '*'
for (#11 = #3-#10; #11 < #3+#10+1; #11++) {
Goto_Col(#11-1)
if (Cur_Char==Cur_Char(2)) { #21=' ' } else { #21='*' }
Ins_Char(#20, OVERWRITE)
#20 = #21
}
Ins_Char(#21, OVERWRITE)
Ins_Char('*', OVERWRITE)
}
Recursive
Vedit macro language does not have recursive functions, so some pushing and popping is needed to implement recursion.
#1 = 1 // x
#2 = 1 // y
#3 = 16 // length (height of the triangle / 2)
#4 = 5 // depth of recursion
Buf_Switch(Buf_Free) // Open a new buffer for output
Ins_Newline(#3*2) // Create as many empty lines as needed
Call("Triangle") // Draw the triangle
BOF
Return
:Triangle:
if (#4 == 0) {
Goto_Line(#2)
EOL Ins_Char(' ', COUNT, #1-Cur_Col+1) // add spaces if needed
Goto_Col(#1)
Ins_Char('*', OVERWRITE)
} else {
Num_Push(1,4)
#2 += #3; #3 /= 2; #4--; Call("Triangle")
Num_Pop(1,4)
Num_Push(1,4)
#1 += #3; #3 /= 2; #4--; Call("Triangle")
Num_Pop(1,4)
Num_Push(1,4)
#1 += 2*#3; #2 += #3; #3 /= 2; #4--; Call("Triangle")
Num_Pop(1,4)
}
Return
Wren
var size = 1 << 4
for (y in size-1..0) {
System.write(" " * y)
for (x in 0...size-y) System.write((x&y != 0) ? " " : "* ")
System.print()
}
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
X86 Assembly
Translation of XPL0. Assemble with tasm, tlink /t
.model tiny
.code
.486
org 100h
start: xor ebx, ebx ;S1:= 0
mov edx, 8000h ;S2:= $8000
mov cx, 16 ;for I:= Size downto 1
tri10: mov ebx, edx ; S1:= S2
tri15: test edx, edx ; while S2#0
je tri20
mov al, '*' ; ChOut
test dl, 01h ; if S2&1 then '*' else ' '
jne tri18
mov al, ' '
tri18: int 29h
shr edx, 1 ; S2>>1
jmp tri15
tri20: mov al, 0Dh ;new line
int 29h
mov al, 0Ah
int 29h
shl ebx, 1 ;S2:= S2 xor S1<<1
xor edx, ebx
shr ebx, 2 ;S2:= S2 xor S1>>1
xor edx, ebx
loop tri10 ;next I
ret
end start
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
XPL0
code ChOut=8, CrLf=9;
def Order=4, Size=1<<Order;
int S1, S2, I;
[S1:= 0; S2:= $8000;
for I:= 0 to Size-1 do
[S1:= S2;
while S2 do
[ChOut(0, if S2&1 then ^* else ^ ); S2:= S2>>1];
CrLf(0);
S2:= S2 xor S1<<1;
S2:= S2 xor S1>>1;
];
]
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Yabasic
sub rep$(n, c$)
local i, s$
for i = 1 to n
s$ = s$ + c$
next
return s$
end sub
sub sierpinski(n)
local lim, y, x
lim = 2**n - 1
for y = lim to 0 step -1
print rep$(y, " ");
for x = 0 to lim-y
if and(x, y) then print " "; else print "* "; end if
next
print
next
end sub
for i = 1 to 5
sierpinski(i)
next
zkl
level,d := 3,T("*");
foreach n in (level + 1){
sp:=" "*(2).pow(n);
d=d.apply('wrap(a){ String(sp,a,sp) }).extend(
d.apply(fcn(a){ String(a," ",a) }));
}
d.concat("\n").println();
- Output:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Programming Tasks
- Fractals
- 11l
- 8080 Assembly
- 8086 Assembly
- ACL2
- Action!
- Ada
- ALGOL 68
- ALGOL W
- AppleScript
- Arturo
- ATS
- AutoHotkey
- APL
- AWK
- BASH (feat. sed & tr)
- BASIC
- BASIC256
- BBC BASIC
- FreeBASIC
- IS-BASIC
- BCPL
- Befunge
- Burlesque
- BQN
- C
- C sharp
- C++
- Clojure
- CLU
- COBOL
- Comal
- Common Lisp
- Cowgol
- D
- Delphi
- Draco
- DWScript
- E
- Elixir
- Elm
- Erlang
- Euphoria
- Excel
- F Sharp
- Factor
- FALSE
- FALSE examples needing attention
- Examples needing attention
- FOCAL
- Forth
- Fortran
- GAP
- Gnuplot
- Go
- Golfscript
- Groovy
- Haskell
- Haxe
- Hoon
- Icon
- Unicon
- Icon Programming Library
- IDL
- J
- Java
- JavaFX Script
- JavaScript
- Jq
- Julia
- Kotlin
- Liberty BASIC
- Logo
- Lua
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- NetRexx
- Nim
- OCaml
- Oforth
- Oz
- PARI/GP
- Pascal
- Perl
- Phix
- Phixmonti
- PHP
- Picat
- PicoLisp
- PL/I
- PL/M
- Pop11
- PostScript
- PowerShell
- Processing
- Prolog
- PureBasic
- Python
- Quackery
- R
- Racket
- Raku
- REXX
- Ring
- Ruby
- Run BASIC
- Rust
- Scala
- Scheme
- Seed7
- Sidef
- Swift
- Tcl
- TI-83 BASIC
- UBasic/4tH
- Unlambda
- Ursala
- VBA
- VBScript
- Vedit macro language
- Wren
- X86 Assembly
- XPL0
- Yabasic
- Zkl
- Pages with too many expensive parser function calls