Sierpinski triangle: Difference between revisions
(→{{header|Ruby}}: add method) |
m (Highlighting, new lines) |
||
Line 84: | Line 84: | ||
{{works with|ALGOL 68|Standard - no extensions to language used}} |
{{works with|ALGOL 68|Standard - no extensions to language used}} |
||
{{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 algol>PROC sierpinski = (INT n)[]STRING: ( |
<lang algol>PROC sierpinski = (INT n)[]STRING: ( |
||
Line 301: | Line 303: | ||
The only 'special' thing here is that the math is done in a byte array, filled with the numbers 32 and 42 and then output through a "<tt>string(array)</tt>" which prints the ascii representation of each individual element in the array. |
The only 'special' thing here is that the math is done in a byte array, filled with the numbers 32 and 42 and then output through a "<tt>string(array)</tt>" which prints the ascii representation of each individual element in the array. |
||
⚫ | |||
<pre> |
|||
⚫ | |||
s = (t = bytarr(3+2^(n+1))+32b) |
s = (t = bytarr(3+2^(n+1))+32b) |
||
t[2^n+1] = 42b |
t[2^n+1] = 42b |
||
Line 309: | Line 310: | ||
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b |
for i=1,n_elements(t)-2 do if s[i-1] eq s[i+1] then t[i]=32b else t[i]=42b |
||
end |
end |
||
end |
end</lang> |
||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
Line 316: | Line 316: | ||
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: |
||
|._31]\,(,.~,])^:4,:'* ' |
<lang j> |._31]\,(,.~,])^:4,:'* '</lang> |
||
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: |
||
' *'{~'1'=(-|."_1[:":2|!/~)i.-16 |
<lang j> ' *'{~'1'=(-|."_1[:":2|!/~)i.-16</lang> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 348: | Line 348: | ||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
{{works with|Java|1.5+}} |
|||
⚫ | |||
import java.util.*; |
<lang java>import java.util.*; |
||
public class Sierpinski |
public class Sierpinski |
||
Line 375: | Line 375: | ||
System.out.println(x); |
System.out.println(x); |
||
} |
} |
||
⚫ | |||
} |
|||
⚫ | |||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
<lang javascript> |
<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] = ' '; |
|||
line[n] = '*'; |
|||
for (i=0; i<n; ++i) { |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
t = (line[j-1] == line[j+1] ? ' ' : '*'); |
|||
line[j-1] = u; |
|||
u = t; |
|||
} |
|||
line[n+i] = t; |
|||
line[n+i+1] = '*'; |
|||
} |
|||
line[n+i+1] = '*'; |
|||
} |
|||
⚫ | |||
} |
|||
⚫ | |||
⚫ | |||
⚫ | |||
triangle(6); |
|||
⚫ | |||
</lang> |
|||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
This will draw a graphical Sierpinski gasket using turtle graphics. |
This will draw a graphical Sierpinski gasket using turtle graphics. |
||
<lang logo>to sierpinski :n :length |
|||
if :n = 0 [stop] |
|||
repeat 3 [sierpinski :n-1 :length/2 fd :length rt 120] |
|||
end |
|||
seth 30 sierpinski 5 200</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
<lang ocaml> |
<lang ocaml>let sierpinski n = |
||
let sierpinski n = |
|||
let rec loop down space n = |
let rec loop down space n = |
||
if n = 0 then |
if n = 0 then |
||
Line 423: | Line 419: | ||
let () = |
let () = |
||
List.iter print_endline (sierpinski 4) |
List.iter print_endline (sierpinski 4)</lang> |
||
</lang> |
|||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 496: | Line 491: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
<lang perl> |
<lang perl>sub sierpinski { |
||
sub sierpinski { |
|||
my ($n) = @_; |
my ($n) = @_; |
||
my @down = '*'; |
my @down = '*'; |
||
Line 508: | Line 502: | ||
} |
} |
||
print "$_\n" foreach sierpinski 4; |
print "$_\n" foreach sierpinski 4;</lang> |
||
</lang> |
|||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
Line 515: | Line 508: | ||
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). |
||
⚫ | |||
<pre> |
|||
⚫ | |||
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 536: | Line 528: | ||
enddefine; |
enddefine; |
||
triangle(4); |
triangle(4);</lang> |
||
</pre> |
|||
Alternative solution, keeping all triangle as list of strings |
Alternative solution, keeping all triangle as list of strings |
||
⚫ | |||
<pre> |
|||
⚫ | |||
lvars acc = ['*'], spaces = ' ', j; |
lvars acc = ['*'], spaces = ' ', j; |
||
for j from 1 to n do |
for j from 1 to n do |
||
Line 551: | Line 541: | ||
enddefine; |
enddefine; |
||
triangle2(4); |
triangle2(4);</lang> |
||
</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
<lang python> |
<lang python>def sierpinski(n): |
||
def sierpinski(n): |
|||
d = ["*"] |
d = ["*"] |
||
for i in xrange(n): |
for i in xrange(n): |
||
Line 563: | Line 551: | ||
return d |
return d |
||
print "\n".join(sierpinski(4)) |
print "\n".join(sierpinski(4))</lang> |
||
</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 585: | Line 572: | ||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
<lang scheme> |
<lang scheme>(define (sierpinski n) |
||
(define (sierpinski n) |
|||
(for-each |
(for-each |
||
(lambda (x) (display (list->string x)) (newline)) |
(lambda (x) (display (list->string x)) (newline)) |
||
Line 597: | Line 583: | ||
(map (lambda (x) (append x (list #\ ) x)) acc)) |
(map (lambda (x) (append x (list #\ ) x)) acc)) |
||
(append spaces spaces) |
(append spaces spaces) |
||
(- n 1)))))) |
(- n 1))))))</lang> |
||
</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 632: | Line 617: | ||
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. |
||
⚫ | |||
<pre> |
|||
⚫ | |||
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 650: | Line 634: | ||
Ins_Char(#21, OVERWRITE) |
Ins_Char(#21, OVERWRITE) |
||
Ins_Char('*', OVERWRITE) |
Ins_Char('*', OVERWRITE) |
||
⚫ | |||
} |
|||
</pre> |
|||
===Recursive=== |
===Recursive=== |
||
Line 657: | Line 640: | ||
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. |
||
⚫ | |||
<pre> |
|||
⚫ | |||
#2 = 1 // y |
#2 = 1 // y |
||
#3 = 16 // length (height of the triangle / 2) |
#3 = 16 // length (height of the triangle / 2) |
||
Line 686: | Line 668: | ||
Num_Pop(1,4) |
Num_Pop(1,4) |
||
} |
} |
||
Return |
Return</lang> |
||
</pre> |
Revision as of 17:27, 17 June 2009
You are encouraged to solve this task according to the task description, using any language you may know.
Produce an ASCII representation of a Sierpinski triangle of order N. For example, the Sierpinski triangle of order 4 should look like this:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
See also Sierpinski carpet
Ada
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; 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;</lang>
ALGOL 68
<lang algol>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)))</lang>
BASIC
<lang freebasic>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
CLS triangle 1,1,16,5</lang>
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.
C
This solution uses a cellular automaton (rule 90) with a proper initial status.
<lang c>#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);
}</lang>
<lang c>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);
}</lang>
<lang c>int main() {
sierpinski_triangle(4); return EXIT_SUCCESS;
}</lang>
Common Lisp
<lang 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) "*" " ")))))</lang>
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.
D
Adapted from Java version (this version is slower than the Python one). <lang d>import std.stdio, std.string;
string[] sierpinski(int n) {
string[] parts = ["*"]; string space = " "; for (int i; i < n; i++) { string[] parts2; foreach (x; parts) parts2 ~= space ~ x ~ space; foreach (x; parts) parts2 ~= x ~ " " ~ x; parts = parts2; space ~= space; } return parts;
}
void main() {
writefln(sierpinski(4).join("\n"));
}</lang>
That sierpinski() function can run at compile time too, so with a compile-time join it can compute the whole result at compile-time:
<lang d> string[] sierpinski(int n) {
string[] parts = ["*"]; string space = " "; for (int i; i < n; i++) { string[] parts2; foreach (x; parts) parts2 ~= space ~ x ~ space; foreach (x; parts) parts2 ~= x ~ " " ~ x; parts = parts2; space ~= space; } return parts;
}
string joinCT(string[] parts, char sep) {
string result; if (parts.length) { foreach (part; parts[0 .. $-1]) { result ~= part; result ~= sep; } result ~= parts[$-1]; } return result;
}
pragma(msg, sierpinski(4).joinCT('\n'));
void main() {} </lang>
E
<lang 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() }
}</lang>
<lang e>? printSierpinski(4, stdout)</lang>
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
Haskell
<lang haskell> sierpinski 0 = ["*"]
sierpinski (n+1) = map ((space ++) . (++ space)) down ++ map (unwords . replicate 2) down where down = sierpinski n space = replicate (2^n) ' ' printSierpinski = mapM_ putStrLn . sierpinski</lang>
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.
<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</lang>
J
There are any number of succinct ways to produce this in J. Here's one that exploits self-similarity:
<lang j> |._31]\,(,.~,])^:4,:'* '</lang>
Here's one that leverages the relationship between Sierpinski's and Pascal's triangles:
<lang j> ' *'{~'1'=(-|."_1[:":2|!/~)i.-16</lang>
Java
<lang java>public static void triangle(int n){
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>
<lang java>import java.util.*;
public class Sierpinski {
public static List<String> sierpinski(int n) { List<String> down = Arrays.asList("*"); String space = " "; for (int i = 0; i < n; i++) { 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; space += space; } return down; }
public static void main(String[] args) { for (String x : sierpinski(4)) System.out.println(x); }
}</lang>
JavaScript
<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] = ' '; line[n] = '*'; for (i=0; i<n; ++i) { document.write(line.join()+"\n"); u ='*'; for(j=n-i; j<n+i+1; ++j) { t = (line[j-1] == line[j+1] ? ' ' : '*'); line[j-1] = u; u = t; } line[n+i] = t; line[n+i+1] = '*'; }
}
document.write("
\n"); triangle(6); document.write("
");</lang>
Logo
This will draw a graphical Sierpinski gasket using turtle graphics. <lang logo>to sierpinski :n :length
if :n = 0 [stop] repeat 3 [sierpinski :n-1 :length/2 fd :length rt 120]
end seth 30 sierpinski 5 200</lang>
OCaml
<lang 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)</lang>
Pascal
<lang 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;</lang>
<lang pascal>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;</lang>
<lang pascal>begin
triangle(4)
end.</lang>
Perl
<lang perl>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;</lang>
Pop11
Solution using line buffer in an integer array oline, 0 represents ' ' (space), 1 represents '*' (star). <lang pop11>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);</lang>
Alternative solution, keeping all triangle as list of strings <lang pop11>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);</lang>
Python
<lang 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))</lang>
Ruby
From the command line: <lang bash>ruby -le'16.times{|y|print" "*(15-y),(0..y).map{|x|~y&x>0?" ":" *"}}'</lang>
or,
<lang ruby>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.join("\n")
end
puts sierpinski_triangle(4)</lang>
Scheme
<lang scheme>(define (sierpinski n)
(for-each (lambda (x) (display (list->string x)) (newline)) (let loop ((acc (list (list #\*))) (spaces (list #\ )) (n n)) (if (zero? n) acc (loop (append (map (lambda (x) (append spaces x spaces)) acc) (map (lambda (x) (append x (list #\ ) x)) acc)) (append spaces spaces) (- n 1))))))</lang>
Tcl
<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]</lang>
Vedit macro language
Iterative
The macro writes the fractal into an edit buffer where it can be viewed and saved to file if required. This allows creating images larger than screen, the size is only limited by free disk space. <lang vedit>#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)
}</lang>
Recursive
Vedit macro language does not have recursive functions, so some pushing and popping is needed to implement recursion. <lang vedit>#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</lang>