Skip to content

Commit 5380940

Browse files
committed
Permutations implementation.
1 parent 564d0ec commit 5380940

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+434
-202
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Methods dealing with lists (strings/arrays etc.) and objects.
3333
Full list coming soon.
3434

3535
### Needed
36-
- [ ] - Implementations of the `scan*` methods?
36+
- [x] - ~~Implementations of the `scan*` methods?~~ Implemented as of version `0.21.0`
3737
- [ ] - "" of the Math methods?
3838
- [ ] - A friendly function names module has to be built
3939
for some of these functions as most javascript developers

dist/amd/uncurried/_listOps.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ define(['exports', './_jsPlatform/_list', './_jsPlatform/_function', './_functio
44
Object.defineProperty(exports, "__esModule", {
55
value: true
66
});
7-
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;
7+
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;
88
exports.map = _map.map;
99

1010

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

270265

266+
/**
267+
* Same as `subsequences` but returns an `Array.<Type>` instead
268+
* of an array of arrays. **Note:** `Type` here means
269+
* a string, an instance of array, or some indexable-like type.
270+
* @function module:_listOps.subsequences1
271+
* @jsperftest https://jsperf.com/subsequences
272+
* @param xs {Array|String}
273+
* @returns {Array.<(Array|String|*)>}
274+
*/
275+
subsequences1 = exports.subsequences1 = xs => {
276+
const listLen = (0, _objectOps.length)(xs),
277+
len = Math.pow(2, listLen),
278+
aggregator = (0, _utils.aggregatorByType)(xs),
279+
out = [];
280+
for (let i = 0; i < len; i += 1) {
281+
let entry = (0, _objectOps.of)(xs);
282+
for (let j = 0; j < listLen; j += 1) {
283+
if (i & 1 << j) {
284+
entry = aggregator(entry, xs[j]);
285+
}
286+
}
287+
out.push(entry);
288+
}
289+
return out;
290+
},
291+
292+
271293
/**
272294
* Returns a list of permutations for passed in list.
273295
* Use caution with lists above a length of 15 (will take long due to nature of
@@ -278,7 +300,7 @@ define(['exports', './_jsPlatform/_list', './_jsPlatform/_function', './_functio
278300
*/
279301
permutations = exports.permutations = xs => {
280302
const limit = (0, _objectOps.length)(xs);
281-
return !limit ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
303+
return !limit || limit === 1 ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
282304
},
283305

284306

dist/amd/uncurried/_listOps/_utils.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ define(['exports', './_aggregation', '../_jsPlatform/_function', '../_jsPlatform
2929
* @param arr {Array|String|*}
3030
* @returns {Array|String|*}
3131
*/
32-
sliceFrom = exports.sliceFrom = (startInd, arr) => (0, _list.slice)(startInd, (0, _object.length)(arr), arr),
32+
sliceFrom = exports.sliceFrom = (startInd, arr) => (0, _list.slice)(startInd, undefined, arr),
3333

3434

3535
/**
@@ -242,16 +242,15 @@ define(['exports', './_aggregation', '../_jsPlatform/_function', '../_jsPlatform
242242
list[ind2] = tmp;
243243
return list;
244244
},
245-
_permutationsAlgo = exports._permutationsAlgo = (listIn, limit, remainderLen) => {
246-
let out = [];
245+
_permutationsAlgo = exports._permutationsAlgo = (listIn, limit, remainderLen, out = []) => {
247246
if (remainderLen === 1) {
248-
return copy(listIn);
247+
out.push(copy(listIn));return out;
249248
}
250249
for (let i = 0; i < remainderLen; i++) {
251250
const newLen = remainderLen - 1;
252251

253252
// Capture permutation
254-
out.push(_permutationsAlgo(listIn, limit, newLen));
253+
_permutationsAlgo(listIn, limit, newLen, out);
255254

256255
// If remainderLen is odd, swap first and last element
257256
// else, swap `ith` and last element

dist/cjs/uncurried/_listOps.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Object.defineProperty(exports, "__esModule", {
44
value: true
55
});
6-
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;
6+
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;
77

88
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"); } }; }(); /**
99
* List operations module.
@@ -289,11 +289,6 @@ transpose = exports.transpose = function transpose(xss) {
289289
* @returns {Array.<Array>}
290290
*/
291291
subsequences = exports.subsequences = function subsequences(xs) {
292-
// if (isset(xs) && !xs.hasOwnProperty('length')) {
293-
// throw new Error('`sub-sequences` function can only operate on values that have a `length` property and ' +
294-
// 'have index-able properties (`obj[0] //etc... (Arrays, strings etc.)`). ' +
295-
// 'Type given "' + typeOf(xs) + '". Given `toString`: "' + xs + '";');
296-
// }
297292
var listLen = (0, _objectOps.length)(xs),
298293
len = Math.pow(2, listLen),
299294
out = [];
@@ -310,6 +305,33 @@ subsequences = exports.subsequences = function subsequences(xs) {
310305
},
311306

312307

308+
/**
309+
* Same as `subsequences` but returns an `Array.<Type>` instead
310+
* of an array of arrays. **Note:** `Type` here means
311+
* a string, an instance of array, or some indexable-like type.
312+
* @function module:_listOps.subsequences1
313+
* @jsperftest https://jsperf.com/subsequences
314+
* @param xs {Array|String}
315+
* @returns {Array.<(Array|String|*)>}
316+
*/
317+
subsequences1 = exports.subsequences1 = function subsequences1(xs) {
318+
var listLen = (0, _objectOps.length)(xs),
319+
len = Math.pow(2, listLen),
320+
aggregator = (0, _utils.aggregatorByType)(xs),
321+
out = [];
322+
for (var i = 0; i < len; i += 1) {
323+
var entry = (0, _objectOps.of)(xs);
324+
for (var j = 0; j < listLen; j += 1) {
325+
if (i & 1 << j) {
326+
entry = aggregator(entry, xs[j]);
327+
}
328+
}
329+
out.push(entry);
330+
}
331+
return out;
332+
},
333+
334+
313335
/**
314336
* Returns a list of permutations for passed in list.
315337
* Use caution with lists above a length of 15 (will take long due to nature of
@@ -320,7 +342,7 @@ subsequences = exports.subsequences = function subsequences(xs) {
320342
*/
321343
permutations = exports.permutations = function permutations(xs) {
322344
var limit = (0, _objectOps.length)(xs);
323-
return !limit ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
345+
return !limit || limit === 1 ? [xs] : (0, _utils._permutationsAlgo)(xs, limit, limit);
324346
},
325347

326348

dist/cjs/uncurried/_listOps/_utils.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ var
4343
* @returns {Array|String|*}
4444
*/
4545
sliceFrom = exports.sliceFrom = function sliceFrom(startInd, arr) {
46-
return (0, _list.slice)(startInd, (0, _object.length)(arr), arr);
46+
return (0, _list.slice)(startInd, undefined, arr);
4747
},
4848

4949

@@ -278,15 +278,16 @@ findWhere = exports.findWhere = function findWhere(pred, xs) {
278278
return list;
279279
},
280280
_permutationsAlgo = exports._permutationsAlgo = function _permutationsAlgo(listIn, limit, remainderLen) {
281-
var out = [];
281+
var out = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
282+
282283
if (remainderLen === 1) {
283-
return copy(listIn);
284+
out.push(copy(listIn));return out;
284285
}
285286
for (var i = 0; i < remainderLen; i++) {
286287
var newLen = remainderLen - 1;
287288

288289
// Capture permutation
289-
out.push(_permutationsAlgo(listIn, limit, newLen));
290+
_permutationsAlgo(listIn, limit, newLen, out);
290291

291292
// If remainderLen is odd, swap first and last element
292293
// else, swap `ith` and last element

dist/es6-module/fjl.js

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ const map$1 = (fn, xs) => {
324324
* @module listOpsUtils_
325325
* @private
326326
*/
327-
const sliceFrom = (startInd, arr) => slice(startInd, length(arr), arr);
327+
const sliceFrom = (startInd, arr) => slice(startInd, undefined, arr);
328328
const sliceTo = (toInd, xs) => slice(0, toInd, xs);
329329
const copy = xs => sliceFrom(0, xs);
330330
const genericAscOrdering = (a, b) => {
@@ -417,14 +417,13 @@ const _swap = (list, ind1, ind2) => {
417417
list[ind2] = tmp;
418418
return list;
419419
};
420-
const _permutationsAlgo = (listIn, limit, remainderLen) => {
421-
let out = [];
422-
if (remainderLen === 1) { return copy(listIn); }
420+
const _permutationsAlgo = (listIn, limit, remainderLen, out = []) => {
421+
if (remainderLen === 1) { out.push(copy(listIn)); return out; }
423422
for (let i = 0; i < remainderLen; i++) {
424423
const newLen = remainderLen - 1;
425424

426425
// Capture permutation
427-
out.push(_permutationsAlgo(listIn, limit, newLen));
426+
_permutationsAlgo(listIn, limit, newLen, out);
428427

429428
// If remainderLen is odd, swap first and last element
430429
// else, swap `ith` and last element
@@ -518,11 +517,6 @@ const transpose = xss => {
518517
return filter$1(x => length(x), outLists);
519518
};
520519
const subsequences = xs => {
521-
// if (isset(xs) && !xs.hasOwnProperty('length')) {
522-
// throw new Error('`sub-sequences` function can only operate on values that have a `length` property and ' +
523-
// 'have index-able properties (`obj[0] //etc... (Arrays, strings etc.)`). ' +
524-
// 'Type given "' + typeOf(xs) + '". Given `toString`: "' + xs + '";');
525-
// }
526520
const listLen = length(xs),
527521
len = Math.pow(2, listLen),
528522
out = [];
@@ -539,7 +533,7 @@ const subsequences = xs => {
539533
};
540534
const permutations = xs => {
541535
const limit = length(xs);
542-
return !limit ? [xs] :
536+
return !limit || limit === 1 ? [xs] :
543537
_permutationsAlgo(xs, limit, limit);
544538
};
545539
const foldl = reduce$1;

dist/iife/fjl.js

Lines changed: 6 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/iife/fjl.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/iife/fjl.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)