2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -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;
}

View file

@ -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] = '&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;
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");
triangle(6);

View 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);