Pascal's triangle: Difference between revisions

Line 309:
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]]);
}</lang>
Functional style:
<lang d>import std.stdio, std.algorithm, std.range;
 
auto pascal(int n) {
auto p = [[1]];
foreach (_; 0 .. n)
p ~= array(map!q{a[0] + a[1]}(zip(p[$-1] ~ 0, 0 ~ p[$-1])));
return p;
}
 
void main() {
writeln(pascal(5));
}</lang>
Output:
<pre>[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]]</pre>
There is similarity between Pascal's triangle and [[Sierpinski triangle]]. Their difference are the initial line and the operation that act on the line element to produce next line. The following is a generic pascal's triangle implementation for positive number of lines output (n).
<lang d>import std.stdio, std.string, std.format : fmx = format ;
 
string Pascal(alias dg, T, T initValue)(int n) {
string output ;
void append(T[] l) {
output ~= repeat(" ", (n - l.length + 1)*2) ;
foreach(e; l) output ~= fmx("%4s", fmx("%4s",e)) ;
output ~= "\n" ;
}
if(n > 0) {
T[][] lines = [[initValue]] ;
append(lines[0]) ;
for(int i = 1 ; i < n ; i++) {
lines ~= lines[i-1] ~ initValue ; // length + 1
for(int j = 1 ; j < lines[i-1].length ; j++)
lines[i][j] = dg(lines[i-1][j], lines[i-1][j-1]) ;
append(lines[i]) ;
}
}
return output ;
}
 
string delegate(int n) GenericPascal(alias dg, T, T initValue)(){
mixin Pascal!(dg, T, initValue) ;
return &Pascal ;
}
 
char xor(char a, char b) { return a == b ? '_' : '*' ; }
 
void main() {
auto pascal = GenericPascal!((int a, int b) { return a + b; }, int, 1) ;
auto sierpinski = GenericPascal!(xor, char, '*') ;
 
foreach(i ; [1,5,9]) writef(pascal(i)) ;
// an order 4 sierpinski triangle is a 2^4 lines generic
// pascal triangle with xor operation
foreach(i ; [16]) writef(sierpinski(i)) ;
}</lang>
Output:
Anonymous user