initial functionality commit

This commit is contained in:
71846 2018-03-16 14:42:55 +00:00
parent 567474ce00
commit 7d15bfe58a
4 changed files with 208 additions and 0 deletions

View file

@ -0,0 +1,181 @@
import Utils from "../Utils.js";
/**
*
*/
class SetOps {
/**
*
*/
constructor() {
this._sampleDelimiter = "\\n\\n";
this._operation = ["Union", "Intersection", "Set Difference", "Symmetric Difference", "Cartesian Product", "Power Set"];
this._itemDelimiter = ",";
}
/**
*
*/
get OPERATION() {
return this._operation;
}
/**
*
*/
get SAMPLE_DELIMITER() {
return this._sampleDelimiter;
}
/**
*
*/
get ITEM_DELIMITER() {
return this._itemDelimiter;
}
/**
*
* @param {*} input
* @param {*} args
*/
runSetOperation(input, args) {
const [sampleDelim, itemDelimiter, operation] = args;
const sets = input.split(sampleDelim);
if (!sets || (sets.length !== 2 && operation !== "Power Set") || (sets.length !== 1 && operation === "Power Set")) {
return "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?";
}
if (this._operation.indexOf(operation) === -1) {
return "Invalid 'Operation' option.";
}
let result = {
Union: this.runUnion,
Intersection: this.runIntersect,
"Set Difference": this.runSetDifference,
"Symmetric Difference": this.runSymmetricDifference,
"Cartesian Product": this.runCartesianProduct,
"Power Set": this.runPowerSet(itemDelimiter),
}[operation]
.apply(null, sets.map(s => s.split(itemDelimiter)));
// Formatting issues due to the nested characteristics of power set.
if (operation === "Power Set") {
result = result.map(i => `${i}\n`).join("");
} else {
result = result.join(itemDelimiter);
}
return Utils.escapeHtml(result);
}
/**
*
* @param {*} a
* @param {*} a
*/
runUnion(a, b) {
const result = {};
/**
*
* @param {*} r
*/
const addUnique = (hash) => (item) => {
if (!hash[item]) {
hash[item] = true;
}
};
a.map(addUnique(result));
b.map(addUnique(result));
return Object.keys(result);
}
/**
*
* @param {*} a
* @param {*} b
*/
runIntersect(a, b) {
return a.filter((item) => {
return b.indexOf(item) > -1;
});
}
/**
*
* @param {*} a
* @param {*} b
*/
runSetDifference(a, b) {
return a.filter((item) => {
return b.indexOf(item) === -1;
});
}
/**
*
* @param {*} a
* @param {*} b
*/
runSymmetricDifference(a, b) {
/**
*
* @param {*} refArray
*/
const getDifference = (refArray) => (item) => {
return refArray.indexOf(item) === -1;
};
return a
.filter(getDifference(b))
.concat(b.filter(getDifference(a)));
}
/**
*
* @param {*} a
* @param {*} b
*/
runCartesianProduct(a, b) {
return Array(Math.max(a.length, b.length))
.fill(null)
.map((item, index) => `(${a[index] || undefined},${b[index] || undefined})`);
}
/**
*
* @param {*} a
*/
runPowerSet(delimiter) {
return function(a) {
/**
*
* @param {*} dec
*/
const toBinary = (dec) => (dec >>> 0).toString(2);
const result = new Set();
const maxBinaryValue = parseInt(Number(a.map(i => "1").reduce((p, c) => p + c)), 2);
const binaries = [...Array(maxBinaryValue + 1).keys()]
.map(toBinary)
.map(i => i.padStart(toBinary(maxBinaryValue).length, "0"));
binaries.forEach((binary) => {
const split = binary.split("");
result.add(a.filter((item, index) => split[index] === "1"));
});
// map for formatting & put in length order.
return [...result].map(r => r.join(delimiter)).sort((a, b) => a.length - b.length);
};
}
}
export default new SetOps();