2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,81 +1,58 @@
|
|||
// A Sierpinski triangle of order N,
|
||||
// constructed as Pascal's triangle mod 2
|
||||
// and mapped to 2^N lines of centred {1:asterisk, 0:space} strings
|
||||
(function (order) {
|
||||
|
||||
(function (n) {
|
||||
var nRows = Math.pow(2, n),
|
||||
lstSierpinski = sierpinski(nRows).map(asciiBinary),
|
||||
// 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];
|
||||
|
||||
nBaseWidth = lstSierpinski[nRows - 1].length;
|
||||
// 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);
|
||||
|
||||
return lstSierpinski.map(
|
||||
function (s) {
|
||||
return centreAligned(s, nBaseWidth);
|
||||
}
|
||||
).join('\n');
|
||||
})(4);
|
||||
|
||||
// A Sierpinski sieve of n rows
|
||||
// (Pascal triangle mod 2)
|
||||
// n --> [bool]
|
||||
function sierpinski(n) {
|
||||
return pascalTriangle(n).map(
|
||||
function (line) {
|
||||
return line.map(function (x) {
|
||||
return x % 2;
|
||||
});
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// A Pascal triangle of n rows
|
||||
// n --> [[n]]
|
||||
function pascalTriangle(n) {
|
||||
|
||||
// Sums of each consecutive pair of numbers
|
||||
// [n] --> [n]
|
||||
function pairSums(lst) {
|
||||
return lst.reduce(function (acc, n, i, l) {
|
||||
var iPrev = i ? i - 1 : 0;
|
||||
return i ? acc.concat(l[iPrev] + l[i]) : acc
|
||||
}, []);
|
||||
}
|
||||
|
||||
// Next line in a Pascal triangle series
|
||||
// [n] --> [n]
|
||||
function nextPascal(lst) {
|
||||
return lst.length ? [1].concat(
|
||||
pairSums(lst)
|
||||
).concat(1) : [1];
|
||||
}
|
||||
|
||||
// Each row is a function of the preceding row
|
||||
return n ? Array.apply(null, Array(n - 1)).reduce(
|
||||
function (a, _, i) {
|
||||
return a.concat(
|
||||
[nextPascal(a[i])]
|
||||
);
|
||||
}, [
|
||||
[1]
|
||||
]
|
||||
) : [];
|
||||
}
|
||||
|
||||
// [bool] --> s
|
||||
function asciiBinary(lst) {
|
||||
return lst.map(
|
||||
function (x) {
|
||||
return x ? '*' : ' ';
|
||||
}
|
||||
).join(' ');
|
||||
}
|
||||
|
||||
// Space-padded to left and right
|
||||
// s --> n --> s
|
||||
function centreAligned(s, n) {
|
||||
var lngWhite = n - s.length,
|
||||
lngMargin = lngWhite > 0 ? Math.ceil(lngWhite / 2) : 0,
|
||||
strMargin = lngMargin ? Array(lngMargin + 1).join(' ') : '';
|
||||
|
||||
return strMargin ? strMargin + s + strMargin : s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
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;
|
||||
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] = '*';
|
||||
}
|
||||
line[n+i] = t;
|
||||
line[n+i+1] = '*';
|
||||
}
|
||||
}
|
||||
document.write("<pre>\n");
|
||||
triangle(6);
|
||||
|
|
|
|||
67
Task/Sierpinski-triangle/JavaScript/sierpinski-triangle-3.js
Normal file
67
Task/Sierpinski-triangle/JavaScript/sierpinski-triangle-3.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// A Sierpinski triangle of order N,
|
||||
// constructed as 2^N lines of Pascal's triangle mod 2
|
||||
// and mapped to centred {1:asterisk, 0:space} strings
|
||||
|
||||
(order => {
|
||||
|
||||
// sierpinski :: Int -> [Bool]
|
||||
let sierpinski = intOrder => {
|
||||
|
||||
// asciiPascalMod2 :: Int -> [[Int]]
|
||||
let asciiPascalMod2 = nRows =>
|
||||
range(1, nRows - 1)
|
||||
.reduce(sofar => {
|
||||
let lstPrev = sofar.slice(-1)[0];
|
||||
|
||||
// The composition of (asciiBinary . mod 2 . add)
|
||||
// is reduced here to a rule from two parent characters
|
||||
// to a single child character.
|
||||
|
||||
// Rule 90 also reduces to the same XOR
|
||||
// relationship between left and right neighbours.
|
||||
|
||||
return sofar
|
||||
.concat([zipWith(
|
||||
(left, right) => left === right ? ' ' : '*',
|
||||
[' '].concat(lstPrev),
|
||||
lstPrev.concat(' ')
|
||||
)]);
|
||||
}, [
|
||||
['*'] // Tip of triangle
|
||||
]);
|
||||
|
||||
// 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
|
||||
return asciiPascalMod2(Math.pow(2, intOrder))
|
||||
.reduceRight((a, x) => {
|
||||
return {
|
||||
triangle: a.indent + x.join(' ') + '\n' + a.triangle,
|
||||
indent: a.indent + ' '
|
||||
}
|
||||
}, {
|
||||
triangle: '',
|
||||
indent: ''
|
||||
}).triangle
|
||||
};
|
||||
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
let zipWith = (f, xs, ys) =>
|
||||
xs.length === ys.length ? (
|
||||
xs.map((x, i) => f(x, ys[i]))
|
||||
) : undefined,
|
||||
|
||||
// range(intFrom, intTo, optional intStep)
|
||||
// Int -> Int -> Maybe Int -> [Int]
|
||||
range = (m, n, step) => {
|
||||
let d = (step || 1) * (n >= m ? 1 : -1);
|
||||
|
||||
return Array.from({
|
||||
length: Math.floor((n - m) / d) + 1
|
||||
}, (_, i) => m + (i * d));
|
||||
};
|
||||
|
||||
return sierpinski(order);
|
||||
|
||||
})(4);
|
||||
Loading…
Add table
Add a link
Reference in a new issue