Skip to content

Commit

Permalink
Permutations implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
elycruz committed Jan 29, 2018
1 parent 564d0ec commit 5380940
Show file tree
Hide file tree
Showing 52 changed files with 434 additions and 202 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Methods dealing with lists (strings/arrays etc.) and objects.
Full list coming soon.

### Needed
- [ ] - Implementations of the `scan*` methods?
- [x] - ~~Implementations of the `scan*` methods?~~ Implemented as of version `0.21.0`
- [ ] - "" of the Math methods?
- [ ] - A friendly function names module has to be built
for some of these functions as most javascript developers
Expand Down
36 changes: 29 additions & 7 deletions dist/amd/uncurried/_listOps.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ define(['exports', './_jsPlatform/_list', './_jsPlatform/_function', './_functio
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.complement = exports.difference = exports.intersectBy = exports.intersect = exports.union = exports.unionBy = exports.removeFirstsBy = exports.removeBy = exports.nubBy = exports.insertBy = exports.insert = exports.sortBy = exports.sortOn = exports.sort = exports.remove = exports.nub = exports.scanr1 = exports.scanr = exports.scanl1 = exports.scanl = exports.minimum = exports.maximum = exports.product = exports.sum = exports.not = exports.or = exports.and = exports.all = exports.any = exports.unzipN = exports.unzip = exports.zipWith5 = exports.zipWith4 = exports.zipWith3 = exports.zipWithN = exports.zipWith = exports.zip5 = exports.zip4 = exports.zip3 = exports.zipN = exports.zip = exports.stripPrefix = exports.tails = exports.inits = exports.groupBy = exports.group = exports.isSubsequenceOf = exports.isInfixOf = exports.isSuffixOf = exports.isPrefixOf = exports.lookup = exports.notElem = exports.elem = exports.partition = exports.filter = exports.find = exports.at = exports.breakOnList = exports.span = exports.dropWhileEnd = exports.dropWhile = exports.takeWhile = exports.splitAt = exports.drop = exports.take = exports.elemIndices = exports.elemIndex = exports.findIndices = exports.findIndex = exports.unfoldr = exports.cycle = exports.replicate = exports.repeat = exports.iterate = exports.mapAccumR = exports.mapAccumL = exports.foldr1 = exports.foldl1 = exports.foldr = exports.foldl = exports.permutations = exports.subsequences = exports.transpose = exports.intercalate = exports.intersperse = exports.reverse = exports.concatMap = exports.concat = exports.unconsr = exports.uncons = exports.init = exports.tail = exports.last = exports.head = exports.appendMany = exports.append = exports.map = undefined;
exports.complement = exports.difference = exports.intersectBy = exports.intersect = exports.union = exports.unionBy = exports.removeFirstsBy = exports.removeBy = exports.nubBy = exports.insertBy = exports.insert = exports.sortBy = exports.sortOn = exports.sort = exports.remove = exports.nub = exports.scanr1 = exports.scanr = exports.scanl1 = exports.scanl = exports.minimum = exports.maximum = exports.product = exports.sum = exports.not = exports.or = exports.and = exports.all = exports.any = exports.unzipN = exports.unzip = exports.zipWith5 = exports.zipWith4 = exports.zipWith3 = exports.zipWithN = exports.zipWith = exports.zip5 = exports.zip4 = exports.zip3 = exports.zipN = exports.zip = exports.stripPrefix = exports.tails = exports.inits = exports.groupBy = exports.group = exports.isSubsequenceOf = exports.isInfixOf = exports.isSuffixOf = exports.isPrefixOf = exports.lookup = exports.notElem = exports.elem = exports.partition = exports.filter = exports.find = exports.at = exports.breakOnList = exports.span = exports.dropWhileEnd = exports.dropWhile = exports.takeWhile = exports.splitAt = exports.drop = exports.take = exports.elemIndices = exports.elemIndex = exports.findIndices = exports.findIndex = exports.unfoldr = exports.cycle = exports.replicate = exports.repeat = exports.iterate = exports.mapAccumR = exports.mapAccumL = exports.foldr1 = exports.foldl1 = exports.foldr = exports.foldl = exports.permutations = exports.subsequences1 = exports.subsequences = exports.transpose = exports.intercalate = exports.intersperse = exports.reverse = exports.concatMap = exports.concat = exports.unconsr = exports.uncons = exports.init = exports.tail = exports.last = exports.head = exports.appendMany = exports.append = exports.map = undefined;
exports.map = _map.map;


Expand Down Expand Up @@ -247,11 +247,6 @@ define(['exports', './_jsPlatform/_list', './_jsPlatform/_function', './_functio
* @returns {Array.<Array>}
*/
subsequences = exports.subsequences = xs => {
// if (isset(xs) && !xs.hasOwnProperty('length')) {
// throw new Error('`sub-sequences` function can only operate on values that have a `length` property and ' +
// 'have index-able properties (`obj[0] //etc... (Arrays, strings etc.)`). ' +
// 'Type given "' + typeOf(xs) + '". Given `toString`: "' + xs + '";');
// }
const listLen = (0, _objectOps.length)(xs),
len = Math.pow(2, listLen),
out = [];
Expand All @@ -268,6 +263,33 @@ define(['exports', './_jsPlatform/_list', './_jsPlatform/_function', './_functio
},


/**
* Same as `subsequences` but returns an `Array.<Type>` instead
* of an array of arrays. **Note:** `Type` here means
* a string, an instance of array, or some indexable-like type.
* @function module:_listOps.subsequences1
* @jsperftest https://jsperf.com/subsequences
* @param xs {Array|String}
* @returns {Array.<(Array|String|*)>}
*/
subsequences1 = exports.subsequences1 = xs => {
const listLen = (0, _objectOps.length)(xs),
len = Math.pow(2, listLen),
aggregator = (0, _utils.aggregatorByType)(xs),
out = [];
for (let i = 0; i < len; i += 1) {
let entry = (0, _objectOps.of)(xs);
for (let j = 0; j < listLen; j += 1) {
if (i & 1 << j) {
entry = aggregator(entry, xs[j]);
}
}
out.push(entry);
}
return out;
},


/**
* Returns a list of permutations for passed in list.
* Use caution with lists above a length of 15 (will take long due to nature of
Expand All @@ -278,7 +300,7 @@ define(['exports', './_jsPlatform/_list', './_jsPlatform/_function', './_functio
*/
permutations = exports.permutations = xs => {
const limit = (0, _objectOps.length)(xs);
return !limit ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
return !limit || limit === 1 ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
},


Expand Down
9 changes: 4 additions & 5 deletions dist/amd/uncurried/_listOps/_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ define(['exports', './_aggregation', '../_jsPlatform/_function', '../_jsPlatform
* @param arr {Array|String|*}
* @returns {Array|String|*}
*/
sliceFrom = exports.sliceFrom = (startInd, arr) => (0, _list.slice)(startInd, (0, _object.length)(arr), arr),
sliceFrom = exports.sliceFrom = (startInd, arr) => (0, _list.slice)(startInd, undefined, arr),


/**
Expand Down Expand Up @@ -242,16 +242,15 @@ define(['exports', './_aggregation', '../_jsPlatform/_function', '../_jsPlatform
list[ind2] = tmp;
return list;
},
_permutationsAlgo = exports._permutationsAlgo = (listIn, limit, remainderLen) => {
let out = [];
_permutationsAlgo = exports._permutationsAlgo = (listIn, limit, remainderLen, out = []) => {
if (remainderLen === 1) {
return copy(listIn);
out.push(copy(listIn));return out;
}
for (let i = 0; i < remainderLen; i++) {
const newLen = remainderLen - 1;

// Capture permutation
out.push(_permutationsAlgo(listIn, limit, newLen));
_permutationsAlgo(listIn, limit, newLen, out);

// If remainderLen is odd, swap first and last element
// else, swap `ith` and last element
Expand Down
36 changes: 29 additions & 7 deletions dist/cjs/uncurried/_listOps.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.complement = exports.difference = exports.intersectBy = exports.intersect = exports.union = exports.unionBy = exports.removeFirstsBy = exports.removeBy = exports.nubBy = exports.insertBy = exports.insert = exports.sortBy = exports.sortOn = exports.sort = exports.remove = exports.nub = exports.scanr1 = exports.scanr = exports.scanl1 = exports.scanl = exports.minimum = exports.maximum = exports.product = exports.sum = exports.not = exports.or = exports.and = exports.all = exports.any = exports.unzipN = exports.unzip = exports.zipWith5 = exports.zipWith4 = exports.zipWith3 = exports.zipWithN = exports.zipWith = exports.zip5 = exports.zip4 = exports.zip3 = exports.zipN = exports.zip = exports.stripPrefix = exports.tails = exports.inits = exports.groupBy = exports.group = exports.isSubsequenceOf = exports.isInfixOf = exports.isSuffixOf = exports.isPrefixOf = exports.lookup = exports.notElem = exports.elem = exports.partition = exports.filter = exports.find = exports.at = exports.breakOnList = exports.span = exports.dropWhileEnd = exports.dropWhile = exports.takeWhile = exports.splitAt = exports.drop = exports.take = exports.elemIndices = exports.elemIndex = exports.findIndices = exports.findIndex = exports.unfoldr = exports.cycle = exports.replicate = exports.repeat = exports.iterate = exports.mapAccumR = exports.mapAccumL = exports.foldr1 = exports.foldl1 = exports.foldr = exports.foldl = exports.permutations = exports.subsequences = exports.transpose = exports.intercalate = exports.intersperse = exports.reverse = exports.concatMap = exports.concat = exports.unconsr = exports.uncons = exports.init = exports.tail = exports.last = exports.head = exports.appendMany = exports.append = exports.map = undefined;
exports.complement = exports.difference = exports.intersectBy = exports.intersect = exports.union = exports.unionBy = exports.removeFirstsBy = exports.removeBy = exports.nubBy = exports.insertBy = exports.insert = exports.sortBy = exports.sortOn = exports.sort = exports.remove = exports.nub = exports.scanr1 = exports.scanr = exports.scanl1 = exports.scanl = exports.minimum = exports.maximum = exports.product = exports.sum = exports.not = exports.or = exports.and = exports.all = exports.any = exports.unzipN = exports.unzip = exports.zipWith5 = exports.zipWith4 = exports.zipWith3 = exports.zipWithN = exports.zipWith = exports.zip5 = exports.zip4 = exports.zip3 = exports.zipN = exports.zip = exports.stripPrefix = exports.tails = exports.inits = exports.groupBy = exports.group = exports.isSubsequenceOf = exports.isInfixOf = exports.isSuffixOf = exports.isPrefixOf = exports.lookup = exports.notElem = exports.elem = exports.partition = exports.filter = exports.find = exports.at = exports.breakOnList = exports.span = exports.dropWhileEnd = exports.dropWhile = exports.takeWhile = exports.splitAt = exports.drop = exports.take = exports.elemIndices = exports.elemIndex = exports.findIndices = exports.findIndex = exports.unfoldr = exports.cycle = exports.replicate = exports.repeat = exports.iterate = exports.mapAccumR = exports.mapAccumL = exports.foldr1 = exports.foldl1 = exports.foldr = exports.foldl = exports.permutations = exports.subsequences1 = exports.subsequences = exports.transpose = exports.intercalate = exports.intersperse = exports.reverse = exports.concatMap = exports.concat = exports.unconsr = exports.uncons = exports.init = exports.tail = exports.last = exports.head = exports.appendMany = exports.append = exports.map = undefined;

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
* List operations module.
Expand Down Expand Up @@ -289,11 +289,6 @@ transpose = exports.transpose = function transpose(xss) {
* @returns {Array.<Array>}
*/
subsequences = exports.subsequences = function subsequences(xs) {
// if (isset(xs) && !xs.hasOwnProperty('length')) {
// throw new Error('`sub-sequences` function can only operate on values that have a `length` property and ' +
// 'have index-able properties (`obj[0] //etc... (Arrays, strings etc.)`). ' +
// 'Type given "' + typeOf(xs) + '". Given `toString`: "' + xs + '";');
// }
var listLen = (0, _objectOps.length)(xs),
len = Math.pow(2, listLen),
out = [];
Expand All @@ -310,6 +305,33 @@ subsequences = exports.subsequences = function subsequences(xs) {
},


/**
* Same as `subsequences` but returns an `Array.<Type>` instead
* of an array of arrays. **Note:** `Type` here means
* a string, an instance of array, or some indexable-like type.
* @function module:_listOps.subsequences1
* @jsperftest https://jsperf.com/subsequences
* @param xs {Array|String}
* @returns {Array.<(Array|String|*)>}
*/
subsequences1 = exports.subsequences1 = function subsequences1(xs) {
var listLen = (0, _objectOps.length)(xs),
len = Math.pow(2, listLen),
aggregator = (0, _utils.aggregatorByType)(xs),
out = [];
for (var i = 0; i < len; i += 1) {
var entry = (0, _objectOps.of)(xs);
for (var j = 0; j < listLen; j += 1) {
if (i & 1 << j) {
entry = aggregator(entry, xs[j]);
}
}
out.push(entry);
}
return out;
},


/**
* Returns a list of permutations for passed in list.
* Use caution with lists above a length of 15 (will take long due to nature of
Expand All @@ -320,7 +342,7 @@ subsequences = exports.subsequences = function subsequences(xs) {
*/
permutations = exports.permutations = function permutations(xs) {
var limit = (0, _objectOps.length)(xs);
return !limit ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
return !limit || limit === 1 ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
},


Expand Down
9 changes: 5 additions & 4 deletions dist/cjs/uncurried/_listOps/_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ var
* @returns {Array|String|*}
*/
sliceFrom = exports.sliceFrom = function sliceFrom(startInd, arr) {
return (0, _list.slice)(startInd, (0, _object.length)(arr), arr);
return (0, _list.slice)(startInd, undefined, arr);
},


Expand Down Expand Up @@ -278,15 +278,16 @@ findWhere = exports.findWhere = function findWhere(pred, xs) {
return list;
},
_permutationsAlgo = exports._permutationsAlgo = function _permutationsAlgo(listIn, limit, remainderLen) {
var out = [];
var out = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];

if (remainderLen === 1) {
return copy(listIn);
out.push(copy(listIn));return out;
}
for (var i = 0; i < remainderLen; i++) {
var newLen = remainderLen - 1;

// Capture permutation
out.push(_permutationsAlgo(listIn, limit, newLen));
_permutationsAlgo(listIn, limit, newLen, out);

// If remainderLen is odd, swap first and last element
// else, swap `ith` and last element
Expand Down
16 changes: 5 additions & 11 deletions dist/es6-module/fjl.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ const map$1 = (fn, xs) => {
* @module listOpsUtils_
* @private
*/
const sliceFrom = (startInd, arr) => slice(startInd, length(arr), arr);
const sliceFrom = (startInd, arr) => slice(startInd, undefined, arr);
const sliceTo = (toInd, xs) => slice(0, toInd, xs);
const copy = xs => sliceFrom(0, xs);
const genericAscOrdering = (a, b) => {
Expand Down Expand Up @@ -417,14 +417,13 @@ const _swap = (list, ind1, ind2) => {
list[ind2] = tmp;
return list;
};
const _permutationsAlgo = (listIn, limit, remainderLen) => {
let out = [];
if (remainderLen === 1) { return copy(listIn); }
const _permutationsAlgo = (listIn, limit, remainderLen, out = []) => {
if (remainderLen === 1) { out.push(copy(listIn)); return out; }
for (let i = 0; i < remainderLen; i++) {
const newLen = remainderLen - 1;

// Capture permutation
out.push(_permutationsAlgo(listIn, limit, newLen));
_permutationsAlgo(listIn, limit, newLen, out);

// If remainderLen is odd, swap first and last element
// else, swap `ith` and last element
Expand Down Expand Up @@ -518,11 +517,6 @@ const transpose = xss => {
return filter$1(x => length(x), outLists);
};
const subsequences = xs => {
// if (isset(xs) && !xs.hasOwnProperty('length')) {
// throw new Error('`sub-sequences` function can only operate on values that have a `length` property and ' +
// 'have index-able properties (`obj[0] //etc... (Arrays, strings etc.)`). ' +
// 'Type given "' + typeOf(xs) + '". Given `toString`: "' + xs + '";');
// }
const listLen = length(xs),
len = Math.pow(2, listLen),
out = [];
Expand All @@ -539,7 +533,7 @@ const subsequences = xs => {
};
const permutations = xs => {
const limit = length(xs);
return !limit ? [xs] :
return !limit || limit === 1 ? [xs] :
_permutationsAlgo(xs, limit, limit);
};
const foldl = reduce$1;
Expand Down
16 changes: 6 additions & 10 deletions dist/iife/fjl.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/iife/fjl.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/iife/fjl.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 5380940

Please sign in to comment.