Last active
November 7, 2019 16:15
-
-
Save geovanisouza92/6d3a07bacd50dfc2321b4ddcfbcc19fd to your computer and use it in GitHub Desktop.
Cartesian Product algo Benchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Benchmark = require('benchmark'); | |
const suite = new Benchmark.Suite(); | |
const A = Array(3).fill(null).map((_, index) => index + 1); | |
const B = A.map((a) => [a, a * -1]); | |
suite | |
.add('cartesianProduct_gen', function () { for (const _ of cartesianProduct_gen(B.slice())) { } }) | |
.add('cartesianProduct_loop', function () { for (const _ of cartesianProduct_loop(...B.slice())) { } }) | |
.add('cartesianProduct_genLoop', function () { for (const _ of cartesianProduct_genLoop(B.slice())) { } }) | |
.add('cartesianProduct_rsp', function () { for (const _ of cartesianProduct_rsp(...B.slice())) { } }) | |
.add('cartesianProduct_sebnukem', function () { for (const _ of cartesianProduct_sebnukem(B.slice())) { } }) | |
// add listeners | |
.on('cycle', function (event) { console.log(String(event.target)); }) | |
.on('complete', function () { console.log('Fastest is ' + this.filter('fastest').map('name')); }) | |
// run async | |
.run({ 'async': true }); | |
function* cartesianProduct_gen(elements) { | |
if (!elements.length) { | |
return; | |
} | |
const end = elements.length - 1; | |
function* appendMore(acc, start) { | |
const head = elements[start]; | |
const hasReachedEnd = start === end; | |
for (const it of head) { | |
const accCopy = acc.slice().concat(it); | |
if (hasReachedEnd) { | |
yield accCopy; | |
} else { | |
yield* appendMore(accCopy, start + 1); | |
} | |
} | |
} | |
yield* appendMore([], 0); | |
} | |
function cartesianProduct_loop() { | |
const N = arguments.length; | |
var arr_lengths = Array(N); | |
var digits = Array(N); | |
var num_tot = 1; | |
for (var i = 0; i < N; ++i) { | |
const len = arguments[i].length; | |
if (!len) { | |
num_tot = 0; | |
break; | |
} | |
digits[i] = 0; | |
num_tot *= (arr_lengths[i] = len); | |
} | |
var ret = Array(num_tot); | |
for (var num = 0; num < num_tot; ++num) { | |
var item = Array(N); | |
for (var j = 0; j < N; ++j) { item[j] = arguments[j][digits[j]]; } | |
ret[num] = item; | |
for (var idx = 0; idx < N; ++idx) { | |
if (digits[idx] == arr_lengths[idx] - 1) { | |
digits[idx] = 0; | |
} else { | |
digits[idx] += 1; | |
break; | |
} | |
} | |
} | |
return ret; | |
} | |
function* cartesianProduct_genLoop(aListOfList) { | |
const outputSize = aListOfList.length; | |
const indexes = Array(outputSize).fill(0); | |
while (true) { | |
// Emit | |
yield indexes.map((a, index) => aListOfList[index][a]); | |
// Update indexes | |
let j = indexes.length - 1; | |
while (true) { | |
indexes[j] += 1; | |
if (indexes[j] < aListOfList[j].length) { | |
break; | |
} | |
indexes[j] = 0; | |
j -= 1; | |
if (j < 0) { | |
return; | |
} | |
} | |
} | |
} | |
const _f = (a, b) => [].concat(...a.map(d => b.map(e => [].concat(d, e)))); | |
const cartesianProduct_rsp = (a, b, ...c) => b ? cartesianProduct_rsp(_f(a, b), ...c) : a; | |
function cartesianProduct_sebnukem(a) { | |
var i, j, l, m, a1, o = []; | |
if (!a || a.length == 0) return a; | |
a1 = a.splice(0, 1)[0]; | |
a = cartesianProduct_sebnukem(a); | |
for (i = 0, l = a1.length; i < l; i++) { | |
if (a && a.length) for (j = 0, m = a.length; j < m; j++) | |
o.push([a1[i]].concat(a[j])); | |
else | |
o.push([a1[i]]); | |
} | |
return o; | |
} |
Author
geovanisouza92
commented
Jul 3, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment