Sierpinski triangle: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|REXX}}: added/changed comments, changed indentation, increased the maximum order the REXX program can handle. -- ~~~~)
(255 intermediate revisions by 72 users not shown)
Line 1: Line 1:
{{task|Fractals}}
{{task|Fractals}}

Produce an ASCII representation of a [[wp:Sierpinski triangle|Sierpinski triangle]] of order N. For example, the Sierpinski triangle of order 4 should look like this:
;Task
Produce an ASCII representation of a [[wp:Sierpinski triangle|Sierpinski triangle]] of order   '''N'''.


;Example
The Sierpinski triangle of order   '''4'''   should look like this:
<pre>
<pre>
*
*
Line 20: Line 26:
</pre>
</pre>



See [[Sierpinski triangle/Graphical]] for graphics images of this pattern. See also [[Sierpinski carpet]]
;Related tasks
* [[Sierpinski triangle/Graphical]] for graphics images of this pattern.
* [[Sierpinski carpet]]
<br><br>

=={{header|11l}}==
{{trans|Python}}

<syntaxhighlight lang="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"))</syntaxhighlight>

{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|8080 Assembly}}==
<syntaxhighlight lang="8080asm">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,'$'</syntaxhighlight>

{{out}}

For order 4 (default if no given):

<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

=={{header|8086 Assembly}}==
<syntaxhighlight lang="asm">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,'$'</syntaxhighlight>

{{out}}

For order 4 (default if no order given):

<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|ACL2}}==
=={{header|ACL2}}==
<lang Lisp>(defun pascal-row (prev)
<syntaxhighlight lang="lisp">(defun pascal-row (prev)
(if (endp (rest prev))
(if (endp (rest prev))
(list 1)
(list 1)
Line 61: 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)))</lang>
height)))</syntaxhighlight>

=={{header|Action!}}==
<syntaxhighlight lang="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</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Sierpinski_triangle.png Screenshot from Atari 8-bit computer]
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>


=={{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.
<lang ada>with Ada.Text_Io; use Ada.Text_Io;
<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 117: Line 356:
Sierpinski(N);
Sierpinski(N);
end loop;
end loop;
end Sieteri_Triangles;</lang>
end Sieteri_Triangles;</syntaxhighlight>


alternative using modular arithmetic:
alternative using modular arithmetic:
<lang Ada>with Ada.Command_Line;
<syntaxhighlight lang="ada">with Ada.Command_Line;
with Ada.Text_IO;
with Ada.Text_IO;


Line 147: Line 386:
end if;
end if;
Sierpinski (N);
Sierpinski (N);
end Main;</lang>
end Main;</syntaxhighlight>
{{out}}
output:
<pre>XXXXXXXXXXXXXXXX
<pre>XXXXXXXXXXXXXXXX
X X X X X X X X
X X X X X X X X
Line 171: 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}} -->
<lang algol68>PROC sierpinski = (INT n)[]STRING: (
<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 186: Line 425:
);
);


printf(($gl$,sierpinski(4)))</lang>
printf(($gl$,sierpinski(4)))</syntaxhighlight>

=={{header|ALGOL W}}==
{{Trans|C}}
<syntaxhighlight lang="algolw">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.</syntaxhighlight>

=={{header|AppleScript}}==
{{Trans|JavaScript}}
{{Trans|Haskell}}
Centering any previous triangle block over two adjacent duplicates:
<syntaxhighlight lang="applescript">------------------- 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</syntaxhighlight>
{{Out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

Or generating each line as an XOR / Rule 90 / Pascal triangle rewrite of the previous line.
{{Trans|JavaScript}}
<syntaxhighlight lang="applescript">----------- 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</syntaxhighlight>
{{Out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|Arturo}}==

<syntaxhighlight lang="rebol">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</syntaxhighlight>

{{out}}

<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

=={{header|ATS}}==
<syntaxhighlight lang="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] *)
</syntaxhighlight>


=={{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]
<lang autohotkey>Loop 6
<syntaxhighlight lang="autohotkey">Loop 6
MsgBox % Triangle(A_Index)
MsgBox % Triangle(A_Index)


Line 208: 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>
}</lang>


=={{header|APL}}==
<syntaxhighlight lang="apl">A←67⍴0⋄A[34]←1⋄' #'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A]</syntaxhighlight>



=={{header|AWK}}==
=={{header|AWK}}==
<lang AWK># WST.AWK - Waclaw Sierpinski's triangle contributed by Dan Nielsen
<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 233: Line 868:
}
}
exit(0)
exit(0)
}</lang>
}</syntaxhighlight>

=={{header|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.
<syntaxhighlight lang="bash">
#!/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' ' *'
</syntaxhighlight>

=={{header|Bash}}==

{{trans|BASH (feat. sed & tr)}}
{{works with|Bash|3.2.57}}
{{works with|Bash|5.2.9}}

<syntaxhighlight lang="bash">
#!/bin/bash

### BASH (pure-bash)
### https://rosettacode.org/wiki/Bourne_Again_SHell
### Ported from bash+sed+tr version
### Tested with bash versions 3.2.57 and 5.2.9
### 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 Bash Parameter Expansion
### ${parameter/pattern/string}
### syntax used for pure-bash global-pattern-substitution.
### (Search "man bash" output for "Parameter Expansion" for additional details
### on the
### ${parameter/pattern/string}
### and
### ${parameter:-word}
### syntax)

# Basic principle:
#
#
# x -> dxd d -> dd s -> s
# xsx dd s
#
# In the end all 'd' and 's' are removed.
function rec(){
if [ $1 == 0 ]
then
echo "x"
else
rec $[ $1 - 1 ] | while read line ; do
A="$line" ; A="${A//d/dd}" ; A="${A//x/dxd}" ; echo "$A"
A="$line" ; A="${A//d/dd}" ; A="${A//x/xsx}" ; echo "$A"
done
fi
}

### If the script has no arguments, then the default is n=4
### Else n is the first argument to the script
export n="${1:-4}"

B="$(rec "$n")" ; B="${B//d/ }" ; B="${B//s/ }" ; B="${B//x/*}"
echo "$B"
</syntaxhighlight>


=={{header|BASIC}}==
=={{header|BASIC}}==
{{works with|QBasic}}
{{works with|QBasic}}
{{works with|FreeBASIC}}
<!-- {{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 -->


<lang qbasic>DECLARE SUB triangle (x AS INTEGER, y AS INTEGER, length AS INTEGER, n AS INTEGER)
<syntaxhighlight lang="qbasic">DECLARE SUB triangle (x AS INTEGER, y AS INTEGER, length AS INTEGER, n AS INTEGER)


CLS
CLS
Line 252: Line 974:
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</lang>
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.



=={{header|BBC BASIC}}==
==={{header|BASIC256}}===
<lang bbcbasic> MODE 8
<syntaxhighlight lang="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
</syntaxhighlight>


==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> MODE 8
OFF
OFF
Line 273: Line 1,015:
PROCsierpinski(x%+l%+l%, y%+l%, l% DIV 2)
PROCsierpinski(x%+l%+l%, y%+l%, l% DIV 2)
ENDIF
ENDIF
ENDPROC</lang>
ENDPROC</syntaxhighlight>

==={{header|FreeBASIC}}===
<syntaxhighlight lang="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)</syntaxhighlight>

==={{header|IS-BASIC}}===
<syntaxhighlight lang="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</syntaxhighlight>

=={{header|BCPL}}==
{{trans|C}}
<syntaxhighlight lang="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')
$)
$)</syntaxhighlight>
{{out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

=={{header|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.

<syntaxhighlight lang="befunge">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<</syntaxhighlight>

=={{header|Burlesque}}==

<syntaxhighlight lang="burlesque">{JPp{
-.'sgve!
J{JL[2./+.' j.*PppP.+PPj.+}m[
j{J" "j.+.+}m[
.+
}{vv{"*"}}PPie} 's sv
4 'sgve!unsh</syntaxhighlight>

=={{header|BQN}}==
<syntaxhighlight lang="bqn">Sierp ← {" •" ⊏˜ (⌽↕2⋆𝕩)⌽˘∾˘∾⟜0¨∧´∘∨⌜˜⥊↕2⥊˜𝕩}</syntaxhighlight>

{{out}}
<pre>
Sierp 3
┌─
╵" •
• •
• •
• • • •
• •
• • • •
• • • •
• • • • • • • • "
</pre>


=={{header|C}}==
=={{header|C}}==
<lang C>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>


#define SIZE (1 << 4)
#define SIZE (1 << 4)
Line 288: Line 1,130:
}
}
return 0;
return 0;
}</lang>
}</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.
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdbool.h>
Line 326: Line 1,168:
}
}
free(cp);
free(cp);
}</lang>
}</syntaxhighlight>


<lang c>void sierpinski_triangle(int n)
<syntaxhighlight lang="c">void sierpinski_triangle(int n)
{
{
int i;
int i;
Line 345: Line 1,187:


free(b);
free(b);
}</lang>
}</syntaxhighlight>


<lang c>int main()
<syntaxhighlight lang="c">int main()
{
{
sierpinski_triangle(4);
sierpinski_triangle(4);
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}</lang>
}</syntaxhighlight>

=={{header|C++}}==
{{works with|C++11}}
A STL-centric recursive solution that uses the new lambda functions in C++11.
<lang cpp>#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;
}</lang>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections;


Line 431: Line 1,234:
}
}
}
}
}</lang>
}</syntaxhighlight>


<lang csharp>namespace RosettaCode {
<syntaxhighlight lang="csharp">namespace RosettaCode {
class Program {
class Program {
static void Main(string[] args) {
static void Main(string[] args) {
Line 440: Line 1,243:
}
}
}
}
}</lang>
}</syntaxhighlight>

{{trans|C}}
{{works with|C sharp|C#|6.0+}}
<syntaxhighlight lang="csharp">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 ? " " : "* ");
}
}
}</syntaxhighlight>


{{trans|OCaml}}
{{trans|OCaml}}
{{works with|C sharp|C#|3.0+}}
{{works with|C sharp|C#|3.0+}}
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
Line 470: Line 1,292:
Console.WriteLine(s);
Console.WriteLine(s);
}
}
}</lang>
}</syntaxhighlight>


Or, with fold / reduce (a.k.a. aggregate):
Or, with fold / reduce (a.k.a. aggregate):


<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
Line 499: Line 1,321:
foreach(string s in Sierpinski(4)) { Console.WriteLine(s); }
foreach(string s in Sierpinski(4)) { Console.WriteLine(s); }
}
}
}</lang>
}</syntaxhighlight>

=={{header|C++}}==
{{works with|C++11}}
A STL-centric recursive solution that uses the new lambda functions in C++11.
<syntaxhighlight lang="cpp">#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;
}</syntaxhighlight>


=={{header|Clojure}}==
=={{header|Clojure}}==
Line 505: Line 1,366:
{{trans|Common Lisp}}
{{trans|Common Lisp}}
With a touch of Clojure's sequence handling.
With a touch of Clojure's sequence handling.
<lang clojure>(ns example
<syntaxhighlight lang="clojure">(ns example
(:require [clojure.contrib.math :as math]))
(:require [clojure.contrib.math :as math]))


Line 530: Line 1,391:
(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)</lang>
(sierpinski-triangle 4)</syntaxhighlight>

=={{header|CLU}}==
{{trans|Fortran}}
<syntaxhighlight lang="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</syntaxhighlight>
{{out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

=={{header|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.
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).</syntaxhighlight>

=={{header|Comal}}==
<syntaxhighlight lang="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</syntaxhighlight>
{{out}}
<pre>Order? 4
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>(defun print-sierpinski (order)
<syntaxhighlight lang="lisp">(defun print-sierpinski (order)
(loop with size = (expt 2 order)
(loop with size = (expt 2 order)
repeat size
repeat size
Line 539: Line 1,516:
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) "*" " ")))))</lang>
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 547: Line 1,524:


Alternate approach:
Alternate approach:
<lang lisp>(defun sierpinski (n)
<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))</lang>
(mapc #'print (sierpinski 4))</syntaxhighlight>

=={{header|Cowgol}}==
<syntaxhighlight lang="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;</syntaxhighlight>

{{out}}

<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|D}}==
=={{header|D}}==
===Run-time Version===
===Run-time Version===
<syntaxhighlight lang="d">void main() /*@safe*/ {
<lang d>import std.stdio, std.algorithm, std.string, std.array;
import std.stdio, std.algorithm, std.string, std.array;


void main() {
enum level = 4;
enum level = 4;
auto d = ["*"];
auto d = ["*"];
foreach (n; 0 .. level) {
foreach (immutable n; 0 .. level) {
const sp = " ".replicate(2 ^^ n);
immutable sp = " ".replicate(2 ^^ n);
d = d.map!(a => sp ~ a ~ sp)().array() ~
d = d.map!(a => sp ~ a ~ sp).array ~
d.map!(a => a ~ " " ~ a)().array();
d.map!(a => a ~ " " ~ a).array;
}
}
d.join("\n").writeln();
d.join('\n').writeln;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> *
<pre> *
Line 585: Line 1,624:
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>
* * * * * * * * * * * * * * * *</pre>

===Compile-time Version===
===Compile-time Version===
Same output.
Same output.
<lang d>import std.string;
<syntaxhighlight lang="d">import std.string, std.range, std.algorithm;


string sierpinski(int n) {
string sierpinski(int level) pure nothrow /*@safe*/ {
auto parts = ["*"];
auto d = ["*"];
auto space = " ";
foreach (immutable i; 0 .. level) {
immutable sp = " ".replicate(2 ^^ i);
foreach (i; 0 .. n) {
d = d.map!(a => sp ~ a ~ sp).array ~
string[] parts2;
foreach (x; parts)
d.map!(a => a ~ " " ~ a).array;
parts2 ~= space ~ x ~ space;
foreach (x; parts)
parts2 ~= x ~ " " ~ x;
parts = parts2;
space ~= space;
}
}
return parts.join("\n");
return d.join('\n');
}
}


pragma(msg, sierpinski(4));
pragma(msg, 4.sierpinski);
void main() {}</lang>
void main() {}</syntaxhighlight>

===Simple Version===
{{trans|C}}
Same output.
<syntaxhighlight lang="d">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;
}</syntaxhighlight>

===Alternative Version===
This uses a different algorithm and shows a different output.
<syntaxhighlight lang="d">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;
}
}</syntaxhighlight>
{{out}}
<pre> #
###

#
###
## ##
#######

#
###
## ##
#######
## ##
#### ####
## ## ## ##
###############

#
###
## ##
#######
## ##
#### ####
## ## ## ##
###############
## ##
#### ####
## ## ## ##
######## ########
## ## ## ##
#### #### #### ####
## ## ## ## ## ## ## ##
###############################

#
###
## ##
#######
## ##
#### ####
## ## ## ##
###############
## ##
#### ####
## ## ## ##
######## ########
## ## ## ##
#### #### #### ####
## ## ## ## ## ## ## ##
###############################
## ##
#### ####
## ## ## ##
######## ########
## ## ## ##
#### #### #### ####
## ## ## ## ## ## ## ##
################ ################
## ## ## ##
#### #### #### ####
## ## ## ## ## ## ## ##
######## ######## ######## ########
## ## ## ## ## ## ## ##
#### #### #### #### #### #### #### ####
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
###############################################################</pre>


=={{header|Delphi}}==
=={{header|Delphi}}==
{{trans|DWScript}}
{{trans|DWScript}}
<lang delphi>program SierpinskiTriangle;
<syntaxhighlight lang="delphi">program SierpinskiTriangle;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 634: Line 1,802:
begin
begin
PrintSierpinski(4);
PrintSierpinski(4);
end.</lang>
end.</syntaxhighlight>

=={{header|Draco}}==
{{trans|C}}
<syntaxhighlight lang="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</syntaxhighlight>
{{out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|DWScript}}==
=={{header|DWScript}}==
{{trans|E}}
{{trans|E}}
<lang delphi>procedure PrintSierpinski(order : Integer);
<syntaxhighlight lang="delphi">procedure PrintSierpinski(order : Integer);
var
var
x, y, size : Integer;
x, y, size : Integer;
Line 655: Line 1,855:


PrintSierpinski(4);
PrintSierpinski(4);
</syntaxhighlight>
</lang>


=={{header|E}}==
=={{header|E}}==
<lang e>def printSierpinski(order, out) {
<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 667: Line 1,867:
out.println()
out.println()
}
}
}</lang>
}</syntaxhighlight>


<lang e>? printSierpinski(4, stdout)</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):
<lang e>def printSierpinski(order, out) {
<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 681: Line 1,881:
out.println()
out.println()
}
}
}</lang>
}</syntaxhighlight>

=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="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)</syntaxhighlight>

=={{header|Elm}}==
{{trans|Haskell}}
<syntaxhighlight lang="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")
]</syntaxhighlight>

Link to live demo: http://dc25.github.io/sierpinskiElm/


=={{header|Erlang}}==
=={{header|Erlang}}==
{{trans|OCaml}}
{{trans|OCaml}}
<lang erlang>-module(sierpinski).
<syntaxhighlight lang="erlang">-module(sierpinski).
-export([triangle/1]).
-export([triangle/1]).


Line 695: Line 1,969:
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).</lang>
triangle(N-1, NewDown, Sp++Sp).</syntaxhighlight>


=={{header|Euphoria}}==
=={{header|Euphoria}}==
{{trans|BASIC}}
{{trans|BASIC}}
<lang euphoria>procedure triangle(integer x, integer y, integer len, integer n)
<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 710: Line 1,984:


clear_screen()
clear_screen()
triangle(1,1,8,4)</lang>
triangle(1,1,8,4)</syntaxhighlight>

=={{header|Excel}}==


===LAMBDA===

Binding the names '''sierpinskiTriangle''', '''sierpCentered''' and '''sierpDoubled''' to the following lambda expressions in the Name Manager of the Excel WorkBook:

(See [https://www.microsoft.com/en-us/research/blog/lambda-the-ultimatae-excel-worksheet-function/ LAMBDA: The ultimate Excel worksheet function])

{{Works with|Office 365 betas 2021}}
<syntaxhighlight lang="lisp">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)
)</syntaxhighlight>

and also assuming the following generic bindings in the Name Manager for the WorkBook:

<syntaxhighlight lang="lisp">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))
)
)
)
)
)</syntaxhighlight>

{{Out}}
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).

{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="16" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=sierpinskiTriangle("▲")(A2)
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
| C
| D
| E
| F
| G
| H
| I
| J
| K
| L
| M
| N
| O
| P
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
| style="font-weight:bold" | 0
| style="text-align:center; background-color:#cbcefb" | ▲
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
| style="font-weight:bold" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
| style="font-weight:bold" | 1
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
| style="font-weight:bold" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
| style="font-weight:bold" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
| style="font-weight:bold" | 2
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 8
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 9
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 10
| style="font-weight:bold" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 11
| style="font-weight:bold" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 12
| style="font-weight:bold" | 3
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 13
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 14
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 15
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 16
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 17
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 18
| style="font-weight:bold" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 19
| style="font-weight:bold" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
| style="text-align:center" |
| style="text-align:center" | ▲
|}

or as strings, using a monospaced font, and the '''wrap text''' alignment setting in Excel:

{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="2" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=gridString(sierpinskiTriangle("*")(A2))
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
| style="font-weight:bold" | Iterations
| style="font-weight:bold" | Sierpinski Triangle
|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
| style="text-align:right" | 0
| style="background-color:#cbcefb" |
*

|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
| style="text-align:right" | 1
|
*
* *

|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
| style="text-align:right" | 2
|
*
* *
* *
* * * *

|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
| style="text-align:right" | 3
|
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *

|-
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
| style="text-align:right" | 4
|
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *

|}


=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==
<lang fsharp>let sierpinski n =
<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 725: Line 2,560:
let () =
let () =
List.iter (fun (i:string) -> System.Console.WriteLine(i)) (sierpinski 4)</lang>
List.iter (fun (i:string) -> System.Console.WriteLine(i)) (sierpinski 4)</syntaxhighlight>

=={{header|FALSE}}==
<lang false>[[$][$1&["*"]?$~1&[" "]?2/]#%"
"]s: { stars }
[$@$@|@@&~&]x: { xor }
[1\[$][1-\2*\]#%]e: { 2^n }
[e;!1\[$][\$s;!$2*x;!\1-]#%%]t:
4t;!</lang>


=={{header|Factor}}==
=={{header|Factor}}==
{{trans|OCaml}}
{{trans|OCaml}}
<lang factor>USING: io kernel math sequences ;
<syntaxhighlight lang="factor">USING: io kernel math sequences ;
IN: sierpinski
IN: sierpinski


Line 753: Line 2,580:


: sierpinski ( n -- )
: sierpinski ( n -- )
[ { "*" } " " ] dip (sierpinski) print ;</lang>
[ { "*" } " " ] dip (sierpinski) print ;</syntaxhighlight>

A more idiomatic version taking advantage of the '''''with''''', '''''each-integer''''', and '''''?''''' combinator as well as leveraging the looping combinator '''''each-integer'''''.
<syntaxhighlight lang="factor">USING: command-line io io.streams.string kernel math math.parser
namespaces sequences ;
IN: sierpinski

: plot ( i j -- )
bitand zero? "* " " " ? write ;

: pad ( n -- )
1 - [ " " write ] times ;

: plot-row ( n -- )
dup 1 + [ tuck - plot ] with each-integer ;

: sierpinski ( n -- )
dup '[ _ over - pad plot-row nl ] each-integer ;</syntaxhighlight>

=={{header|FALSE}}==
Runs correctly in http://www.quirkster.com/iano/js/false-js.html.
Requires the pick character to be substituted with 'O' in the portable interpreter linked-to from https://strlen.com/false-language/.
<syntaxhighlight lang="false">{ print spaces; in:n }
[[$0>][" " 1-]#%]w:

{ left shift; in:x,y out:x<<y }
[[$0>][\2*\ 1-]#%]l:

1 4 l;! { SIZE = 1<<4 }

$ { y = SIZE }
[$0>] { y > 0 }
[1-
$w;!
1ø { x = SIZE }
[$0>]
[1-
1ø$2ø\-&0= { !((x - y) & y) }
$ ["* "]?
~ [" "]?
]#%
10,
]#%%</syntaxhighlight>

=={{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.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)</syntaxhighlight>

{{out}}

<pre>ORDER:4
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|Forth}}==
=={{header|Forth}}==
<lang forth>: stars ( mask -- )
<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 769: Line 2,674:
loop 2drop ;
loop 2drop ;
5 triangle</lang>
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.
<lang fortran>program Sierpinski_triangle
<syntaxhighlight lang="fortran">program Sierpinski_triangle
implicit none
implicit none
Line 802: Line 2,707:
end do
end do
end subroutine Triangle
end subroutine Triangle
end program Sierpinski_triangle</lang>
end program Sierpinski_triangle</syntaxhighlight>


=={{header|GAP}}==
=={{header|GAP}}==
<lang gap># Using parity of binomial coefficients
<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 842: Line 2,747:
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * * </lang>
* * * * * * * * * * * * * * * * </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.


<lang gnuplot># Return a string space or star to print at x,y.
<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 862: Line 2,767:


# 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)</lang>
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.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 891: Line 2,796:
fmt.Println(r)
fmt.Println(r)
}
}
}</lang>
}</syntaxhighlight>

=={{header|Golfscript}}==
Cambia el "3" a un número mayor para un triángulo más grande.
<syntaxhighlight lang="golfscript">' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n*</syntaxhighlight>
{{out}}
<pre>
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\ /__\/__\
/\ /\ /\ /\
/__\ /__\ /__\ /__\
/\ /\ /\ /\ /\ /\ /\ /\
/__\/__\/__\/__\/__\/__\/__\/__\
</pre>


=={{header|Groovy}}==
=={{header|Groovy}}==
Solution:
Solution:
<lang groovy>def stPoints;
<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 910: Line 2,838:
stPoints(order).each { grid[it[0]][it[1]] = (order%10).toString() }
stPoints(order).each { grid[it[0]][it[1]] = (order%10).toString() }
grid
grid
}</lang>
}</syntaxhighlight>


Test:
Test:
<lang groovy>stGrid(0).reverse().each { println it.sum() }
<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 925: Line 2,853:
stGrid(5).reverse().each { println it.sum() }
stGrid(5).reverse().each { println it.sum() }
println()
println()
stGrid(6).reverse().each { println it.sum() }</lang>
stGrid(6).reverse().each { println it.sum() }</syntaxhighlight>


{{out}}
Output:
<pre style="height:30ex;overflow:scroll;">
<pre style="height:30ex;overflow:scroll;">
0
0
Line 1,065: Line 2,993:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>sierpinski 0 = ["*"]
<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 1,071: Line 2,999:
space = replicate (2 ^ (n - 1)) ' '
space = replicate (2 ^ (n - 1)) ' '


main = mapM_ putStrLn $ sierpinski 4</lang>
main = mapM_ putStrLn $ sierpinski 4</syntaxhighlight>
{{out}}
Output:
<pre>
<pre>
*
*
Line 1,089: Line 3,017:
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *</pre>

</pre>
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 0 = ["▲"]
sierpinski n =
[ flip
intercalate
([replicate (2 ^ (n - 1))] <*> " -"),
(<>) <*> ('+' :)
]
>>= (<$> sierpinski (n - 1))

main :: IO ()
main = mapM_ putStrLn $ sierpinski 4</syntaxhighlight>
{{Out}}
<pre> ▲---------------
▲+▲--------------
▲-+ ▲-------------
▲+▲+▲+▲------------
▲---+ ▲-----------
▲+▲--+ ▲+▲----------
▲-+ ▲-+ ▲-+ ▲---------
▲+▲+▲+▲+▲+▲+▲+▲--------
▲-------+ ▲-------
▲+▲------+ ▲+▲------
▲-+ ▲-----+ ▲-+ ▲-----
▲+▲+▲+▲----+ ▲+▲+▲+▲----
▲---+ ▲---+ ▲---+ ▲---
▲+▲--+ ▲+▲--+ ▲+▲--+ ▲+▲--
▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-
▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲</pre>



Using bitwise and between x and y coords:
Using bitwise and between x and y coords:
<lang haskell>import Data.Bits ((.&.))
<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 1,101: Line 3,062:
| otherwise = " "
| otherwise = " "


main = mapM_ putStrLn $ sierpinski 4</lang>
main = mapM_ putStrLn $ sierpinski 4</syntaxhighlight>

{{Trans|JavaScript}}

<syntaxhighlight lang="haskell">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</syntaxhighlight>

Or simply as a right fold:

<syntaxhighlight lang="haskell">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</syntaxhighlight>

{{Out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|Haxe}}==
=={{header|Haxe}}==
<lang haxe>class Main
<syntaxhighlight lang="haxe">class Main
{
{
static function main()
static function main()
Line 1,138: Line 3,165:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|IDL}}==
=={{header|Hoon}}==
<syntaxhighlight lang="hoon">|= n=@ud
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.
=+ m=0
<lang idl>pro sierp,n
=+ o=(reap 1 '*')
s = (t = bytarr(3+2^(n+1))+32b)
t[2^n+1] = 42b
|^ ?: =(m n) o
$(m +(m), o (weld top bot))
for lines = 1,2^n do begin
print,string( (s = t) )
++ gap (fil 3 (pow 2 m) ' ')
++ top (turn o |=(l=@t (rap 3 gap l gap ~)))
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b
++ bot (turn o |=(l=@t (rap 3 l ' ' l ~)))
end
--</syntaxhighlight>
end</lang>


=={{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.
<lang Icon># text based adaptaion of
<syntaxhighlight lang="icon"># text based adaptaion of


procedure main(A)
procedure main(A)
Line 1,167: Line 3,194:
writes((y=1,"\n")|"",canvas[x,y]," ") # print
writes((y=1,"\n")|"",canvas[x,y]," ") # print


end</lang>
end</syntaxhighlight>


{{libheader|Icon Programming Library}}
{{libheader|Icon Programming Library}}
Adapted from [http://www.cs.arizona.edu/icon/library/src/gprogs/sier1.icn graphics/sier1.icn]
Adapted from [http://www.cs.arizona.edu/icon/library/src/gprogs/sier1.icn graphics/sier1.icn]


Sample output for order 3:<pre>Triangle order = 2
{{out|Sample output for order 3}}
<pre>Triangle order = 2


* * * * * * * *
* * * * * * * *
Line 1,182: Line 3,210:
* *
* *
*</pre>
*</pre>

=={{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.
<syntaxhighlight lang="idl">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</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
There are any number of succinct ways to produce this in J. Here's one that exploits self-similarity:
There are any number of succinct ways to produce this in J.
Here's one that exploits self-similarity:
<lang j> |. _31]\ ,(,.~ , ])^:4 ,: '* '</lang>
<syntaxhighlight lang="j"> |. _31]\ ,(,.~ , ])^:4 ,: '* '</syntaxhighlight>

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:
<lang j> ' *' {~ '1' = (- |."_1 [: ": 2 | !/~) i._16</lang>
<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.

(Aside: it's popular to say that booleans are not integers, but this is a false representation of [[Greatest_common_divisor#J|George Boole's work]].)


=={{header|Java}}==
=={{header|Java}}==
Replace translations.
{{trans|JavaScript}}
Recursive solution.
<lang java>public static void triangle(int n){
<syntaxhighlight lang="java">
n= 1 << n;
StringBuilder line= new StringBuilder(); //use a "mutable String"
char t= 0;
char u= 0; // avoid warnings
for(int i= 0;i <= 2 * n;++i)
line.append(" "); //start empty
line.setCharAt(n, '*'); //with the top point of the triangle
for(int i= 0;i < n;++i){
System.out.println(line);
u= '*';
for(int j= n - i;j < n + i + 1;++j){
t= (line.charAt(j - 1) == line.charAt(j + 1) ? ' ' : '*');
line.setCharAt(j - 1, u);
u= t;
}
line.setCharAt(n + i, t);
line.setCharAt(n + i + 1, '*');
}
}</lang>


public class SierpinskiTriangle {
{{trans|Haskell}}
{{works with|Java|1.5+}}
<lang java>import java.util.*;


public static void main(String[] args) {
public class Sierpinski
System.out.println(getSierpinskiTriangle(4));
{
}
public static List<String> sierpinski(int n)
{
private static final String getSierpinskiTriangle(int n) {
List<String> down = Arrays.asList("*");
String space = " ";
if ( n == 0 ) {
for (int i = 0; i < n; i++) {
return "*";
}
List<String> newDown = new ArrayList<String>();
for (String x : down)
newDown.add(space + x + space);
for (String x : down)
newDown.add(x + " " + x);


down = newDown;
String s = getSierpinskiTriangle(n-1);
space += space;
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 down;
return sb.toString();
}
}

public static void main(String[] args)
private static String buildSpace(int n) {
StringBuilder sb = new StringBuilder();
{
for (String x : sierpinski(4))
while ( n > 0 ) {
System.out.println(x);
sb.append(" ");
n--;
}
return sb.toString();
}
}
}</lang>
}
</syntaxhighlight>

{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>


=={{header|JavaFX Script}}==
=={{header|JavaFX Script}}==
{{trans|Python}}
{{trans|Python}}
<lang javafx>function sierpinski(n : Integer) {
<syntaxhighlight lang="javafx">function sierpinski(n : Integer) {
var down = ["*"];
var down = ["*"];
var space = " ";
var space = " ";
Line 1,257: Line 3,322:
}
}


sierpinski(4);</lang>
sierpinski(4);</syntaxhighlight>


=={{header|JavaScript}}==
=={{header|JavaScript}}==

<lang javascript>function triangle(o) {
===ES5===
var n = 1<<o, line = new Array(2*n), i,j,t,u;
====Functional====
for (i=0; i<line.length; ++i) line[i] = '&nbsp;';

line[n] = '*';
Using a functional idiom of JavaScript, we can construct a Sierpinksi triangle as a Pascal triangle (mod 2),
for (i=0; i<n; ++i) {
mapping the binary pattern to centred strings.
document.write(line.join('')+"\n");

u ='*';
<syntaxhighlight lang="javascript">(function (order) {
for(j=n-i; j<n+i+1; ++j) {

t = (line[j-1] == line[j+1] ? '&nbsp;' : '*');
// Sierpinski triangle of order N constructed as
line[j-1] = u;
// Pascal triangle of 2^N rows mod 2
u = t;
// 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);
</syntaxhighlight>

Output (N=4)

<pre> ▲
▲ ▲
▲ ▲
▲ ▲ ▲ ▲
▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲</pre>

====Imperative====

<syntaxhighlight lang="javascript">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] = '&nbsp;';
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] ? '&nbsp;' : '*');
line[j - 1] = u;
u = t;
}
line[n + i] = t;
line[n + i + 1] = '*';
}
}
line[n+i] = t;
line[n+i+1] = '*';
}
}
}
document.write("<pre>\n");
document.write("<pre>\n");
triangle(6);
triangle(6);
document.write("</pre>");</lang>
document.write("</pre>");</syntaxhighlight>

===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:
<syntaxhighlight lang="javascript">(() => {
"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);
})();</syntaxhighlight>

{{Trans|Haskell}}
Centering any preceding triangle block over two adjacent duplicates:
<syntaxhighlight lang="javascript">(() => {
"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();
})();</syntaxhighlight>
{{Out}}
<pre> ▲---------------
▲+▲--------------
▲-+ ▲-------------
▲+▲+▲+▲------------
▲---+ ▲-----------
▲+▲--+ ▲+▲----------
▲-+ ▲-+ ▲-+ ▲---------
▲+▲+▲+▲+▲+▲+▲+▲--------
▲-------+ ▲-------
▲+▲------+ ▲+▲------
▲-+ ▲-----+ ▲-+ ▲-----
▲+▲+▲+▲----+ ▲+▲+▲+▲----
▲---+ ▲---+ ▲---+ ▲---
▲+▲--+ ▲+▲--+ ▲+▲--+ ▲+▲--
▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-+ ▲-
▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲+▲</pre>

Or constructed as 2^N lines of Pascal's triangle mod 2,
and mapped to centred {1:asterisk, 0:space} strings.
<syntaxhighlight lang="javascript">(() => {
"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();
})();</syntaxhighlight>
{{Out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''

'''Preliminaries'''
<syntaxhighlight lang="jq">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;</syntaxhighlight>
<syntaxhighlight lang="jq">
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</syntaxhighlight>
{{out}}
As elsewhere.

=={{header|Julia}}==
{{works with|Julia|0.6}}

<syntaxhighlight lang="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</syntaxhighlight>

=={{header|Kotlin}}==
{{trans|C}}
<syntaxhighlight lang="scala">// 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()
}
}</syntaxhighlight>

{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|Lambdatalk}}==
===1) define===
<syntaxhighlight lang="scheme">
{def sierp
{def sierp.r
{lambda {:order :length :angle}
{if {= :order 0}
then M:length // move :length
else {sierp.r {- :order 1} // recurse
{/ :length 2}
{- :angle}}
T:angle // turn :angle
{sierp.r {- :order 1} // recurse
{/ :length 2}
{+ :angle}}
T:angle // turn :angle
{sierp.r {- :order 1} // recurse
{/ :length 2}
{- :angle}}
}}}
{lambda {:order :length}
{if {= {% :order 2} 0} // if :order is even
then {sierp.r :order :length 60} // recurse with 60°
else T60 // else turn 60°
{sierp.r :order :length -60} // recurse with -60°
}}}
-> sierp
</syntaxhighlight>
===2) draw===
Four curves drawn in 50ms on a PowerBookPro. using the turtle primitive.
<syntaxhighlight lang="scheme">

{svg {@ width="580" height="580" style="box-shadow:0 0 8px #000;"}
{polyline {@ points="{turtle 50 5 0 {sierp 1 570}}"
stroke="#ccc" fill="transparent" stroke-width="7"}}
{polyline {@ points="{turtle 50 5 0 {sierp 3 570}}"
stroke="#8ff" fill="transparent" stroke-width="5"}}
{polyline {@ points="{turtle 50 5 0 {sierp 5 570}}"
stroke="#f88" fill="transparent" stroke-width="3"}}
{polyline {@ points="{turtle 50 5 0 {sierp 7 570}}"
stroke="#000" fill="transparent" stroke-width="1"}}
</syntaxhighlight>
===3) output===
See http://lambdaway.free.fr/lambdawalks/?view=sierpinsky



=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<lang lb>nOrder=4
<syntaxhighlight lang="lb">nOrder=4
call triangle 1, 1, nOrder
call triangle 1, 1, nOrder
end
end
Line 1,295: Line 3,798:
call triangle x+length*2, y+length, n
call triangle x+length*2, y+length, n
END IF
END IF
END SUB</lang>
END SUB</syntaxhighlight>


=={{header|Logo}}==
=={{header|Logo}}==
<lang logo>; Print rows of the triangle from 0 to :limit inclusive.
<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 1,311: Line 3,814:
]
]
print []
print []
]</lang>
]</syntaxhighlight>


=={{header|Mathematica}}==
=={{header|Lua}}==
Ported from the list-comprehension Python version.

<syntaxhighlight lang="lua">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))</syntaxhighlight>
{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|Maple}}==
<syntaxhighlight lang="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:</syntaxhighlight>
{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|Mathematica}}/{{header|Wolfram Language}}==
Cellular automaton (rule 90) based solution:
Cellular automaton (rule 90) based solution:
<lang mathematica>n=4;Grid[CellularAutomaton[90,{{1},0},2^n-1]/.{0->" ",1->"*"},ItemSize->All]</lang>
<syntaxhighlight lang="mathematica">n=4;Grid[CellularAutomaton[90,{{1},0},2^n-1]/.{0->" ",1->"*"},ItemSize->All]</syntaxhighlight>
Using built-in function:
<syntaxhighlight lang="mathematica">SierpinskiMesh[3]</syntaxhighlight>

=={{header|MATLAB}}==
STRING was introduced in version R2016b.
<syntaxhighlight lang="matlab">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)))
</syntaxhighlight>
{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>
===Cellular Automaton Version===
<syntaxhighlight lang="matlab">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)</syntaxhighlight>

===Mixed Version===
<syntaxhighlight lang="matlab">spy(mod(abs(pascal(32,1)),2)==1)</syntaxhighlight>

=={{header|NetRexx}}==
{{trans|Java}}
<syntaxhighlight lang="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
</syntaxhighlight>
{{out}}
<pre>
▲ ▲
▲ ▲
▲ ▲ ▲ ▲
▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
</pre>

=={{header|Nim}}==
{{trans|C}}
<syntaxhighlight lang="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"</syntaxhighlight>

{{out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * * </pre>


=={{header|OCaml}}==
=={{header|OCaml}}==
<lang ocaml>let sierpinski n =
<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 1,330: Line 4,045:


let () =
let () =
List.iter print_endline (sierpinski 4)</lang>
List.iter print_endline (sierpinski 4)</syntaxhighlight>

=={{header|Oforth}}==

This solution uses a cellular automaton (rule 90 for triangle).

automat(rule, n) runs cellular automaton for rule "rule" for n generations.

<syntaxhighlight lang="oforth">: 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 ;</syntaxhighlight>

{{out}}
<pre>
>4 sierpinskiTriangle
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
ok
>
</pre>


=={{header|Oz}}==
=={{header|Oz}}==
<lang oz>declare
<syntaxhighlight lang="oz">declare
fun {NextTriangle Triangle}
fun {NextTriangle Triangle}
Sp = {Spaces {Length Triangle}}
Sp = {Spaces {Length Triangle}}
Line 1,351: Line 4,112:
SierpinskiTriangles = {Iterate NextTriangle ["*"]}
SierpinskiTriangles = {Iterate NextTriangle ["*"]}
in
in
{ForAll {Nth SierpinskiTriangles 5} System.showInfo}</lang>
{ForAll {Nth SierpinskiTriangles 5} System.showInfo}</syntaxhighlight>

=={{header|PARI/GP}}==
{{trans|C}}
<syntaxhighlight lang="parigp">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)</syntaxhighlight>
{{out}}
<pre> *
**
* *
****
* *
** **
* * * *
********
* *
** **
* * * *
**** ****
* * * *
** ** ** **
* * * * * * * *
****************</pre>


=={{header|Pascal}}==
=={{header|Pascal}}==
{{trans|C}}
{{trans|C}}
{{works with|Free Pascal}}
{{works with|Free Pascal}}
<lang pascal>program Sierpinski;
<syntaxhighlight lang="pascal">program Sierpinski;


function ipow(b, n : Integer) : Integer;
function ipow(b, n : Integer) : Integer;
Line 1,373: Line 4,165:
else
else
truth := false
truth := false
end;</lang>
end;</syntaxhighlight>


<lang pascal>function rule_90(ev : String) : String;
<syntaxhighlight lang="pascal">function rule_90(ev : String) : String;
var
var
l, i : Integer;
l, i : Integer;
Line 1,415: Line 4,207:
writeln(b)
writeln(b)
end
end
end;</lang>
end;</syntaxhighlight>


<lang pascal>begin
<syntaxhighlight lang="pascal">begin
triangle(4)
triangle(4)
end.</lang>
end.</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
===version 1===
<lang perl>sub sierpinski {
<syntaxhighlight lang="perl">sub sierpinski {
my ($n) = @_;
my ($n) = @_;
my @down = '*';
my @down = '*';
Line 1,433: Line 4,226:
}
}


print "$_\n" foreach sierpinski 4;</lang>
print "$_\n" foreach sierpinski 4;</syntaxhighlight>


===one-liner===
=={{header|Perl 6}}==
<syntaxhighlight lang="perl">
{{trans|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;}'</syntaxhighlight>
<lang perl6>sub sierpinski ($n) {

my @down = '*';
=={{header|Phix}}==
my $space = ' ';
{{Trans|C}}
for ^$n {
<!--<syntaxhighlight lang="phix">-->
@down = @down.map({"$space$_$space"}), @down.map({"$_ $_"});
<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>
$space ~= $space;
<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: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">lim</span> <span style="color: #008080;">to</span> <span style="color: #000000;">0</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lim</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"* "</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</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;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</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>
<!--</syntaxhighlight>-->
{{out}}
<pre style="font-size: 2px">
*
* *
*
* *
* *
* * * *
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
</pre>

=={{header|Phixmonti}}==
<syntaxhighlight lang="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</syntaxhighlight>

=={{header|PHP}}==

{{Trans|JavaScript}}

<syntaxhighlight lang="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;
}
}
return @down;
}
}

sierpinskiTriangle(4);
.say for sierpinski 4;</lang>
</syntaxhighlight>

{{out}}
<pre> #
# #
# #
# # # #
# #
# # # #
# # # #
# # # # # # # #
# #
# # # #
# # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
</pre>

=={{header|Picat}}==
{{trans|E}}
<syntaxhighlight lang="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.</syntaxhighlight>

{{out}}
<pre> *
* *

*
* *
* *
* * * *

*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *

*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * * </pre>


=={{header|PicoLisp}}==
{{trans|Python}}
<syntaxhighlight lang="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))</syntaxhighlight>


=={{header|PL/I}}==
=={{header|PL/I}}==
<lang PL/I>sierpinski: procedure options (main); /* 2010-03-30 */
<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 1,498: Line 4,500:
end make_triangle;
end make_triangle;


end sierpinski;</lang>
end sierpinski;</syntaxhighlight>


=={{header|PicoLisp}}==
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
{{trans|Python}}
<lang 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 ) )


DECLARE ORDER LITERALLY '4';
(mapc prinl (sierpinski 4))</lang>


/* CP/M BDOS CALL */
=={{header|PostScript}}==
BDOS: PROCEDURE (FN, ARG);
This draws the triangles in a string-rewrite fashion, where all edges form a single polyline. 9 page document showing progession.
DECLARE FN BYTE, ARG ADDRESS;
<lang postscript>%!PS-Adobe-3.0
GO TO 5;
%%BoundingBox 0 0 300 300
END BDOS;


PUT$CHAR: PROCEDURE (CHAR);
/F { 1 0 rlineto } def
DECLARE CHAR BYTE;
/+ { 120 rotate } def
CALL BDOS(2, CHAR);
/- {-120 rotate } def
END PUT$CHAR;
/v {.5 .5 scale } def
/^ { 2 2 scale } def
/!0{ dup 1 sub dup -1 eq not } def


/* PRINT SIERPINSKI TRIANGLE */
/X { !0 { v X + F - X - F + X ^ } { F } ifelse pop } def
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);
0 1 8 { 300 300 scale 0 1 12 div moveto
EOF</syntaxhighlight>
X + F + F fill showpage } for
{{out}}
%%EOF</lang>
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


=={{header|Pop11}}==
=={{header|Pop11}}==
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).
<lang pop11>define triangle(n);
<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 1,555: Line 4,581:
enddefine;
enddefine;


triangle(4);</lang>
triangle(4);</syntaxhighlight>


Alternative solution, keeping all triangle as list of strings
Alternative solution, keeping all triangle as list of strings
<lang pop11>define triangle2(n);
<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 1,568: Line 4,594:
enddefine;
enddefine;


triangle2(4);</lang>
triangle2(4);</syntaxhighlight>

=={{header|PostScript}}==
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

/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</syntaxhighlight>


=={{header|PowerShell}}==
=={{header|PowerShell}}==
{{Trans|JavaScript}}
{{Trans|JavaScript}}
<lang powershell>function triangle($o) {
<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 1,592: Line 4,636:
$line[$n+$i+1] = '█'
$line[$n+$i+1] = '█'
}
}
}</lang>
}</syntaxhighlight>

=={{header|Processing}}==

===Characters in drawing canvas version===
<syntaxhighlight lang="java">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);
}
}</syntaxhighlight>
===Text in console version===
{{trans|Java}}
<syntaxhighlight lang="java">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;
}
</syntaxhighlight>


=={{header|Prolog}}==
=={{header|Prolog}}==
Works with SWI-Prolog;
Works with SWI-Prolog;
<lang Prolog>sierpinski_triangle(N) :-
<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 1,636: Line 4,738:
rule_90(' ',' ','*', '*').
rule_90(' ',' ','*', '*').
rule_90(' ',' ',' ', ' ').
rule_90(' ',' ',' ', ' ').
</syntaxhighlight>
</lang>
{{out}}
Output :
<pre> ?- sierpinski_triangle(4).
<pre> ?- sierpinski_triangle(4).
*
*
Line 1,658: Line 4,760:


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>Procedure Triangle (X,Y, Length, N)
<syntaxhighlight lang="purebasic">Procedure Triangle (X,Y, Length, N)
If N = 0
If N = 0
DrawText( Y,X, "*",#Blue)
DrawText( Y,X, "*",#Blue)
Line 1,677: Line 4,779:
Repeat
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Until WaitWindowEvent()=#PB_Event_CloseWindow
End</lang>
End</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
<lang python>def sierpinski(n):
<syntaxhighlight lang="python">def sierpinski(n):
d = ["*"]
d = ["*"]
for i in xrange(n):
for i in xrange(n):
Line 1,687: Line 4,789:
return d
return d


print "\n".join(sierpinski(4))</lang>
print "\n".join(sierpinski(4))</syntaxhighlight>



Or, using fold / reduce {{works with|Python|3.x}}
Or, using fold / reduce {{works with|Python|3.x}}
<lang python>import functools
<syntaxhighlight lang="python">import functools


def sierpinski(n):
def sierpinski(n):
Line 1,700: Line 4,803:
return functools.reduce(aggregate, range(n), ["*"])
return functools.reduce(aggregate, range(n), ["*"])


print("\n".join(sierpinski(4)))</lang>
print("\n".join(sierpinski(4)))</syntaxhighlight>

and fold/reduce, wrapped as concatMap, can provide the list comprehensions too:
<syntaxhighlight lang="python">'''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))</syntaxhighlight>
{{Out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>


Use Python's long integer and bit operator to make an infinite triangle:
<syntaxhighlight lang="python">x = 1
while True:
print(bin(x)[2:].replace('0', ' '))
x ^= x<<1</syntaxhighlight>

=={{header|Quackery}}==

{{trans|Forth}}

<syntaxhighlight lang="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</syntaxhighlight>

{{out}}

<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>



=={{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.
<lang r>sierpinski.triangle = function(n) {
<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 1,716: Line 4,916:
}
}
}
}
sierpinski.triangle(5)</lang>
sierpinski.triangle(5)</syntaxhighlight>


Shortened to a function of one line.
Shortened to a function of one line.
<lang r>sierpinski.triangle = function(n) {
<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")</lang>
cat(sierpinski.triangle(5),sep="\n")</syntaxhighlight>

=={{header|Racket}}==

<syntaxhighlight lang="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))
</syntaxhighlight>

=={{header|Raku}}==
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku" line>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;</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
<lang rexx>/*REXX program draws a Sierpinski triangle of up to around order 10k. */
<syntaxhighlight lang="rexx">/*REXX program constructs and displays a Sierpinski triangle of up to around order 10k.*/
parse arg n mk . /*get the order of the triangle. */
parse arg n mark . /*get the order of Sierpinski triangle.*/
if n=='' | n==',' then n=4 /*if none specified, assume 4. */
if n=='' | n=="," then n=4 /*Not specified? Then use the default.*/
if mk=='' then mk='*' /*use the default of an asterisk.*/
if mark=='' then mark= "*" /*MARK was specified as a character. */
if length(mk)==2 then mk=x2c(mk) /*MK was specified in hexadecimal*/
if length(mark)==2 then mark=x2c(mark) /* " " " in hexadecimal. */
if length(mk)==3 then mk=d2c(mk) /*MK was specified in decimal. */
if length(mark)==3 then mark=d2c(mark) /* " " " " decimal. */
numeric digits 12000 /*this otta handle the die-hards.*/
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. */</syntaxhighlight>
'''output''' &nbsp; when using the default input of order: &nbsp; <tt> 4 </tt>


(Shown at three quarter size.)
do j=0 for n*4; !=1; z=left('',n*4-1-j) /*indent the line. */
<b>
do k=0 to j /*build the line with J+1 parts*/
<pre style="font-size:75%">
if !//2==0 then z=z' ' /*it's either a blank, or ... */
else z=z mk /*it's one of them thar character*/
!=!*(j-k)%(k+1) /*calculate a handy-dandy thingy.*/
end /*k*/
say z /*display a line of the triangle.*/
end /*j*/
/*stick a fork in it, we're done.*/</lang>
'''output''' (using the default of order 4):
<pre style="overflow:scroll">
*
*
* *
* *
Line 1,761: Line 4,993:
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
</pre>
</pre>
</b>
'''output''' when using the input of: <tt> 8 1e </tt>
'''output''' &nbsp; when using the input of: &nbsp; <tt> 8 &nbsp; 1e </tt>
<pre style="height:30ex;overflow:scroll">

(Shown at half size.)
<b>
<pre style="font-size:50%">
▲ ▲
▲ ▲
Line 1,796: Line 5,032:
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
</pre>
</pre>
</b>
'''output''' when using the input of: <tt> 32 db </tt>
'''output''' &nbsp; when using the input of: &nbsp; <tt> 32 &nbsp; db </tt>
<pre style="height:30ex;overflow:scroll">

(Shown at one tenth size.)
<b>
<pre style="font-size:10%">
█ █
█ █
Line 1,927: Line 5,167:
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
</pre>
</pre>
</b>
Output with an input of 64 was too large for this page. See [[Sierpinski triangle/REXX output 64]]
<br><br>

Output with an input of &nbsp; '''64''' &nbsp; can be viewed at: &nbsp; [[Sierpinski triangle/REXX output 64]]

<br><br>

=={{header|Ring}}==
<syntaxhighlight lang="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
</syntaxhighlight>
Output:
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>


=={{header|Ruby}}==
=={{header|Ruby}}==
From the command line:
From the command line:
<lang ruby>ruby -le'16.times{|y|print" "*(15-y),(0..y).map{|x|~y&x>0?" ":" *"}}'</lang>
<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}}
<lang ruby>def sierpinski_triangle(n)
<syntaxhighlight lang="ruby">def sierpinski_triangle(n)
triangle = ["*"]
triangle = ["*"]
n.times do |i|
n.times do |i|
sp = " " * (2**i)
sp = " " * (2**i)
triangle = triangle.collect {|x| sp + x + sp} + \
triangle = triangle.collect {|x| sp + x + sp} +
triangle.collect {|x| x + " " + x}
triangle.collect {|x| x + " " + x}
end
end
triangle.join("\n")
triangle
end
end


puts sierpinski_triangle(4)</lang>
puts sierpinski_triangle(4)</syntaxhighlight>


Using fold / reduce (aka. inject):
Using fold / reduce (aka. inject):


<lang ruby>def sierpinski_triangle(n)
<syntaxhighlight lang="ruby">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)</syntaxhighlight>
(0..(n-1)).inject(["*"]) {|triangle, i|

space = " " * (2**i)
=={{header|Run BASIC}}==
triangle.map {|x| space + x + space} + triangle.map {|x| x + " " + x}
<syntaxhighlight lang="runbasic">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
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</syntaxhighlight>
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use std::iter::repeat;


fn sierpinski(order: usize) {
puts sierpinski_triangle(4)</lang>
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);
}

</syntaxhighlight>
{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>


=={{header|Scala}}==
=={{header|Scala}}==
The Ruby command-line version (on Windows):
The Ruby command-line version (on Windows):
<lang scala>scala -e "for(y<-0 to 15){println(\" \"*(15-y)++(0 to y).map(x=>if((~y&x)>0)\" \"else\" *\")mkString)}"</lang>
<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:
<lang scala>def sierpinski(n: Int) {
<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 1,972: Line 5,360:
(bitmap << 1) ^ bitmap
(bitmap << 1) ^ bitmap
}
}
}</lang>
}</syntaxhighlight>


The Haskell version:
The Haskell version:
<lang scala>def printSierpinski(n: Int) {
<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 1,986: Line 5,374:
}
}
sierpinski(n) foreach println
sierpinski(n) foreach println
}</lang>
}</syntaxhighlight>


=={{header|Scheme}}==
=={{header|Scheme}}==
{{trans|Haskell}}
{{trans|Haskell}}
<lang scheme>(define (sierpinski n)
<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 2,001: Line 5,389:
(map (lambda (x) (append x (list #\ ) x)) acc))
(map (lambda (x) (append x (list #\ ) x)) acc))
(append spaces spaces)
(append spaces spaces)
(- n 1))))))</lang>
(- n 1))))))</syntaxhighlight>


=={{header|Seed7}}==
=={{header|Seed7}}==
<lang seed7>$ include "seed7_05.s7i";
<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 2,031: Line 5,419:
begin
begin
writeln(join(sierpinski(4), "\n"));
writeln(join(sierpinski(4), "\n"));
end func;</lang>
end func;</syntaxhighlight>

=={{header|SETL}}==
<syntaxhighlight lang="setl">program sierpinski;
const size = 4;

loop for i in [0..size*4-1] do
putchar(' ' * (size*4-1-i));
c := 1;
loop for j in [0..i] do
putchar(if c mod 2=0 then " " else " *" end);
c := c*(i-j) div (j+1);
end loop;
print;
end loop;
end program;</syntaxhighlight>
{{out}}
<pre> *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *</pre>

=={{header|Sidef}}==
<syntaxhighlight lang="ruby">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)</syntaxhighlight>

=={{header|Swift}}==
{{trans|Java}}
<syntaxhighlight lang="text">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] = "*"
}
}</syntaxhighlight>

=={{header|Tcl}}==
{{trans|Perl}}
<syntaxhighlight lang="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]</syntaxhighlight>


=={{header|TI-83 BASIC}}==
=={{header|TI-83 BASIC}}==
Uses Wolfram Rule 90.
Uses Wolfram Rule 90.
<lang ti83b>PROGRAM:SIRPNSKI
<syntaxhighlight lang="ti83b">PROGRAM:SIRPNSKI
:ClrHome
:ClrHome
:Output(1,8,"^")
:Output(1,8,"^")
Line 2,065: Line 5,571:
:L3→L2
:L3→L2
:End
:End
</syntaxhighlight>
</lang>
=={{header|Tcl}}==
{{trans|Perl}}
<lang tcl>package require Tcl 8.5


=={{header|uBasic/4tH}}==
proc map {lambda list} {
<syntaxhighlight lang="text">Input "Triangle order: ";n
foreach elem $list {
n = 2^n
lappend result [apply $lambda $elem]
}
return $result
}


For y = n - 1 To 0 Step -1
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]
}


For i = 0 To y
puts [sierpinski_triangle 4]</lang>
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</syntaxhighlight>


=={{header|Unlambda}}==
=={{header|Unlambda}}==
<lang Unlambda>```ci``s``s`ks``s`k`s``s`kc``s``s``si`kr`k. `k.*k
<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</lang>
`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 2,140: Line 5,645:
=={{header|Ursala}}==
=={{header|Ursala}}==
the straightforward recursive solution
the straightforward recursive solution
<lang Ursala>#import nat
<syntaxhighlight lang="ursala">#import nat


triangle = ~&a^?\<<&>>! ^|RNSiDlrTSPxSxNiCK9xSx4NiCSplrTSPT/~& predecessor</lang>
triangle = ~&a^?\<<&>>! ^|RNSiDlrTSPxSxNiCK9xSx4NiCSplrTSPT/~& predecessor</syntaxhighlight>
the cheeky cellular automaton solution
the cheeky cellular automaton solution
<lang Ursala>#import std
<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/~& :/&</lang>
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)
<lang Ursala>#show+
<syntaxhighlight lang="ursala">#show+


examples = mat0 ~&?(`*!,` !)*** <sierpinski3,triangle4></lang>
examples = mat0 ~&?(`*!,` !)*** <sierpinski3,triangle4></syntaxhighlight>
{{out}}
output:
<pre style="height:30ex;overflow:scroll;">
<pre style="height:30ex;overflow:scroll;">
*
*
Line 2,182: Line 5,687:
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
</pre>
</pre>

=={{header|Uxntal}}==
<syntaxhighlight lang="Uxntal">( uxncli sierpinski.rom )

|100 @on-reset ( -> )

#10 STHk #01 SUB
&ver ( -- )
DUP
#00 EQUk ?{
&pad ( -- )
#2018 DEO
INC GTHk ?&pad
} POP
#00
&fill
ANDk #202a ROT ?{ SWP } POP #18 DEO
#2018 DEO
INC ADDk STHkr LTH ?&fill
POP2
#0a18 DEO
#01 SUB DUP #ff NEQ ?&ver
POP POPr

BRK</syntaxhighlight>

The triangle size is given by the first instruction <code>#10</code>, representing the number of rows to print.

=={{header|VBA}}==
{{Trans|Phix}}<syntaxhighlight lang="vb">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</syntaxhighlight>{{out}}
<pre style="font-size: 4px">
#

# #
#
# #
# #

# # # #
#
# #
# #
# # # #
# #
# # # #
# # # #

# # # # # # # #
#
# #
# #
# # # #
# #
# # # #
# # # #
# # # # # # # #
# #
# # # #
# # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #

# # # # # # # # # # # # # # # #
#
# #
# #
# # # #
# #
# # # #
# # # #
# # # # # # # #
# #
# # # #
# # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# #
# # # #
# # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # #

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # </pre>

=={{header|VBScript}}==
{{trans|PowerShell}}
<syntaxhighlight lang="vb">
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)
</syntaxhighlight>


=={{header|Vedit macro language}}==
=={{header|Vedit macro language}}==
Line 2,188: Line 5,894:
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.
<lang vedit>#3 = 16 // size (height) of the triangle
<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 2,205: Line 5,911:
Ins_Char(#21, OVERWRITE)
Ins_Char(#21, OVERWRITE)
Ins_Char('*', OVERWRITE)
Ins_Char('*', OVERWRITE)
}</lang>
}</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.
<lang vedit>#1 = 1 // x
<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 2,238: Line 5,944:
Num_Pop(1,4)
Num_Pop(1,4)
}
}
Return</lang>
Return</syntaxhighlight>

=={{header|Wren}}==
{{trans|C}}
<syntaxhighlight lang="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()
}</syntaxhighlight>

{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|X86 Assembly}}==
Translation of XPL0. Assemble with tasm, tlink /t
<syntaxhighlight lang="asm"> .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</syntaxhighlight>

{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>


=={{header|XPL0}}==
=={{header|XPL0}}==
<lang XPL0>code ChOut=8, CrLf=9;
<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 2,253: Line 6,039:
S2:= S2 xor S1>>1;
S2:= S2 xor S1>>1;
];
];
]</lang>
]</syntaxhighlight>


{{out}}
Output:
<pre>
<pre>
*
*
Line 2,272: Line 6,058:
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
</pre>

=={{header|Yabasic}}==
{{trans|Phix}}
<syntaxhighlight lang="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
</syntaxhighlight>

=={{header|Zig}}==
{{trans|C}}
<syntaxhighlight lang="zig">const std = @import("std");

pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const size: u16 = 1 << 4;
var y = size;
while (y > 0) {
y -= 1;
for (0..y) |_| try stdout.writeByte(' ');
for (0..size - y) |x| try stdout.writeAll(if (x & y != 0) " " else "* ");
try stdout.writeByte('\n');
}
}</syntaxhighlight>

===Automaton===
{{trans|C}}
{{works with|Zig|0.11.0dev}}
<syntaxhighlight lang="zig">const std = @import("std");
const Allocator = std.mem.Allocator;

pub fn main() !void {
const stdout = std.io.getStdOut().writer();

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

try sierpinski_triangle(allocator, stdout, 4);
}</syntaxhighlight><syntaxhighlight lang="zig">inline fn truth(x: u8) bool {
return x == '*';
}</syntaxhighlight><syntaxhighlight lang="zig">fn rule_90(allocator: Allocator, evstr: []u8) !void {
var cp = try allocator.dupe(u8, evstr);
defer allocator.free(cp); // free does "free" for last node in arena

for (evstr, 0..) |*evptr, i| {
var s = [2]bool{
if (i == 0) false else truth(cp[i - 1]),
if (i + 1 == evstr.len) false else truth(cp[i + 1]),
};
evptr.* = if ((s[0] and !s[1]) or (!s[0] and s[1])) '*' else ' ';
}
}</syntaxhighlight><syntaxhighlight lang="zig">fn sierpinski_triangle(allocator: Allocator, writer: anytype, n: u8) !void {
const len = std.math.shl(usize, 1, n + 1);

var b = try allocator.alloc(u8, len);
defer allocator.free(b);
for (b) |*ptr| ptr.* = ' ';

b[len >> 1] = '*';

try writer.print("{s}\n", .{b});

for (0..len / 2 - 1) |_| {
try rule_90(allocator, b);
try writer.print("{s}\n", .{b});
}
}</syntaxhighlight>

=={{header|zkl}}==
{{trans|D}}
<syntaxhighlight lang="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();</syntaxhighlight>
{{out}}
<pre>
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
</pre>
</pre>

Revision as of 05:01, 1 March 2024

Task
Sierpinski triangle
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



11l

Translation of: Python
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

Translation of: python
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
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

Translation of: C
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

Translation of: JavaScript
Translation of: Haskell

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.

Translation of: JavaScript
----------- 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

A670A[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' '  *'

Bash

Translation of: BASH (feat. sed & tr)
Works with: Bash version 3.2.57
Works with: Bash version 5.2.9
#!/bin/bash

### BASH (pure-bash)
### https://rosettacode.org/wiki/Bourne_Again_SHell
### Ported from bash+sed+tr version
### Tested with bash versions 3.2.57 and 5.2.9
### 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 Bash Parameter Expansion
###     ${parameter/pattern/string}
### syntax used for pure-bash global-pattern-substitution.
### (Search "man bash" output for "Parameter Expansion" for additional details
###  on the
###     ${parameter/pattern/string}
###  and
###     ${parameter:-word}
###  syntax)

# Basic principle:
#
#
#  x ->  dxd       d -> dd      s -> s
#        xsx            dd           s
#
# In the end all 'd' and 's' are removed.
function rec(){
  if [ $1 == 0 ]
  then
    echo "x"
  else
    rec $[ $1 - 1 ] | while read line ; do
      A="$line" ; A="${A//d/dd}" ; A="${A//x/dxd}" ; echo "$A"
      A="$line" ; A="${A//d/dd}" ; A="${A//x/xsx}" ; echo "$A"
    done
  fi
}

### If the script has no arguments, then the default is n=4
### Else n is the first argument to the script
export n="${1:-4}"

B="$(rec "$n")" ; B="${B//d/ }" ; B="${B//s/ }" ; B="${B//x/*}"
echo "$B"

BASIC

Works with: QBasic
Works with: FreeBASIC
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

Translation of: C
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();
        }
    }
}
Translation of: C
Works with: C# version 6.0+
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 ? "  " : "* ");
        }
    }
}
Translation of: OCaml
Works with: C# version 3.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++

Works with: C++11

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

Translation of: Ada
Translation of: Common Lisp

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

Translation of: Fortran
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

Translation of: Fortran

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

Translation of: C

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

Translation of: DWScript
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

Translation of: C
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

Translation of: E
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

Translation of: Erlang
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

Translation of: Haskell
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

Translation of: OCaml
-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

Translation of: BASIC
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

Translation of: OCaml
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 ;

A more idiomatic version taking advantage of the with, each-integer, and ? combinator as well as leveraging the looping combinator each-integer.

USING: command-line io io.streams.string kernel math math.parser
namespaces sequences ;
IN: sierpinski

: plot ( i j -- )
    bitand zero? "* " "  " ? write ;

: pad ( n -- ) 
    1 - [ " " write ] times ;

: plot-row ( n -- ) 
    dup 1 + [ tuck - plot ] with each-integer ;

: sierpinski ( n -- )
    dup '[ _ over - pad plot-row nl ] each-integer ;

FALSE

Runs correctly in http://www.quirkster.com/iano/js/false-js.html. Requires the pick character to be substituted with 'O' in the portable interpreter linked-to from https://strlen.com/false-language/.

{ print spaces; in:n }
[[$0>][" " 1-]#%]w:

{ left shift; in:x,y out:x<<y }
[[$0>][\2*\ 1-]#%]l:

1 4 l;!       { SIZE = 1<<4 }

$             { y = SIZE }
[$0>]         { y > 0 }
[1-
 $w;!
 1ø           { x = SIZE }
 [$0>]
 [1-
  1ø$2ø\-&0=  { !((x - y) & y) }
   $ ["* "]?
   ~ ["  "]?
 ]#%
 10,
]#%%

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

Works with: Fortran version 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.

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
Translation of: JavaScript
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.

# text based adaptaion of 

procedure main(A)

   width := 2 ^ ( 1 + (order := 0 < integer(\A[1]) | 4))  # order of arg[1] or 4
   write("Triangle order= ",order)

   every !(canvas := list(width)) := list(width," ")      # prime the canvas
   every y := 1 to width & x := 1 to width do             # traverse it
      if iand(x - 1, y - 1) = 0 then canvas[x,y] := "*"   # fill

   every x := 1 to width & y := 1 to width do
      writes((y=1,"\n")|"",canvas[x,y]," ")               # print

end

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

Translation of: Python
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] = '&nbsp;';
    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] ? '&nbsp;' : '*');
            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);
})();
Translation of: Haskell

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: 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

Works with: Julia version 0.6
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

Translation of: C
// 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:
               *
              * *
             *   *
            * * * *
           *       *
          * *     * *
         *   *   *   *
        * * * * * * * *
       *               *
      * *             * *
     *   *           *   *
    * * * *         * * * *
   *       *       *       *
  * *     * *     * *     * *
 *   *   *   *   *   *   *   *
* * * * * * * * * * * * * * * *

Lambdatalk

1) define

{def sierp
 {def sierp.r
  {lambda {:order :length :angle} 
   {if {= :order 0}
    then M:length                            // move :length
    else {sierp.r {- :order 1}               // recurse
                  {/ :length 2}
                  {- :angle}}
         T:angle                             // turn :angle
         {sierp.r {- :order 1}               // recurse
                  {/ :length 2} 
                  {+ :angle}}
         T:angle                             // turn :angle
         {sierp.r {- :order 1}               // recurse
                  {/ :length 2} 
                  {- :angle}}
 }}}
 {lambda {:order :length}
  {if {= {% :order 2} 0}                     // if :order is even
   then {sierp.r :order :length 60}          // recurse with 60°
   else T60                                  // else turn 60°
        {sierp.r :order :length -60}         // recurse with -60°
}}}
-> sierp

2) draw

Four curves drawn in 50ms on a PowerBookPro. using the turtle primitive.

{svg {@ width="580" height="580" style="box-shadow:0 0 8px #000;"}
 {polyline  {@ points="{turtle 50 5 0 {sierp 1 570}}"  
               stroke="#ccc" fill="transparent" stroke-width="7"}}
 {polyline  {@ points="{turtle 50 5 0 {sierp 3 570}}"  
               stroke="#8ff" fill="transparent" stroke-width="5"}}
 {polyline  {@ points="{turtle 50 5 0 {sierp 5 570}}"  
               stroke="#f88" fill="transparent" stroke-width="3"}}
 {polyline  {@ points="{turtle 50 5 0 {sierp 7 570}}"  
               stroke="#000" fill="transparent" stroke-width="1"}}

3) output

See http://lambdaway.free.fr/lambdawalks/?view=sierpinsky


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

; 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

Translation of: Java
/* 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

Translation of: C
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

Translation of: C
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

Translation of: C
Works with: Free 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

Translation of: C
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

Translation of: JavaScript
<?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

Translation of: E
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

Translation of: Python
(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

Translation of: JavaScript
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

Translation of: Java
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

Works with: Python version 3.x
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

Translation of: Forth
  [ [ 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)

Translation of: Perl
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,

Translation of: Python
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

Translation of: Haskell
(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;

SETL

program sierpinski;
    const size = 4;

    loop for i in [0..size*4-1] do
        putchar(' ' * (size*4-1-i));
        c := 1;
        loop for j in [0..i] do
            putchar(if c mod 2=0 then "  " else " *" end);
            c := c*(i-j) div (j+1);
        end loop;
        print;
    end loop;
end program;
Output:
                *
               * *
              *   *
             * * * *
            *       *
           * *     * *
          *   *   *   *
         * * * * * * * *
        *               *
       * *             * *
      *   *           *   *
     * * * *         * * * *
    *       *       *       *
   * *     * *     * *     * *
  *   *   *   *   *   *   *   *
 * * * * * * * * * * * * * * * *

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

Translation of: Java
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

Translation of: Perl
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:
        *        
       * *       
      *   *      
     * * * *     
    *       *    
   * *     * *   
  *   *   *   *  
 * * * * * * * * 

               *
              * *
             *   *
            * * * *
           *       *
          * *     * *
         *   *   *   *
        * * * * * * * *
       *               *
      * *             * *
     *   *           *   *
    * * * *         * * * *
   *       *       *       *
  * *     * *     * *     * *
 *   *   *   *   *   *   *   *
* * * * * * * * * * * * * * * *

Uxntal

( uxncli sierpinski.rom )

|100 @on-reset ( -> )

	#10 STHk #01 SUB
	&ver ( -- )
		DUP
		#00 EQUk ?{
			&pad ( -- )
				#2018 DEO
				INC GTHk ?&pad
		} POP 
		#00
		&fill
			ANDk #202a ROT ?{ SWP } POP #18 DEO
			#2018 DEO
			INC ADDk STHkr LTH ?&fill
		POP2
		#0a18 DEO
		#01 SUB DUP #ff NEQ ?&ver
	POP POPr

BRK

The triangle size is given by the first instruction #10, representing the number of rows to print.

VBA

Translation of: Phix
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

Translation of: PowerShell
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

Translation of: JavaScript

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

Translation of: BASIC

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

Translation of: C
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

Translation of: Phix
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

Zig

Translation of: C
const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const size: u16 = 1 << 4;
    var y = size;
    while (y > 0) {
        y -= 1;
        for (0..y) |_| try stdout.writeByte(' ');
        for (0..size - y) |x| try stdout.writeAll(if (x & y != 0) "  " else "* ");
        try stdout.writeByte('\n');
    }
}

Automaton

Translation of: C
Works with: Zig version 0.11.0dev
const std = @import("std");
const Allocator = std.mem.Allocator;

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    try sierpinski_triangle(allocator, stdout, 4);
}
inline fn truth(x: u8) bool {
    return x == '*';
}
fn rule_90(allocator: Allocator, evstr: []u8) !void {
    var cp = try allocator.dupe(u8, evstr);
    defer allocator.free(cp); // free does "free" for last node in arena

    for (evstr, 0..) |*evptr, i| {
        var s = [2]bool{
            if (i == 0) false else truth(cp[i - 1]),
            if (i + 1 == evstr.len) false else truth(cp[i + 1]),
        };
        evptr.* = if ((s[0] and !s[1]) or (!s[0] and s[1])) '*' else ' ';
    }
}
fn sierpinski_triangle(allocator: Allocator, writer: anytype, n: u8) !void {
    const len = std.math.shl(usize, 1, n + 1);

    var b = try allocator.alloc(u8, len);
    defer allocator.free(b);
    for (b) |*ptr| ptr.* = ' ';

    b[len >> 1] = '*';

    try writer.print("{s}\n", .{b});

    for (0..len / 2 - 1) |_| {
        try rule_90(allocator, b);
        try writer.print("{s}\n", .{b});
    }
}

zkl

Translation of: D
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:
               *               
              * *              
             *   *             
            * * * *            
           *       *           
          * *     * *          
         *   *   *   *         
        * * * * * * * *        
       *               *       
      * *             * *      
     *   *           *   *     
    * * * *         * * * *    
   *       *       *       *   
  * *     * *     * *     * *  
 *   *   *   *   *   *   *   * 
* * * * * * * * * * * * * * * *