JSFiddle - React, Tailwind, and code Playground
JavaScript
function powersetLt100Unoptimized(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
var arrCandidate = ps[j].concat(arr[i]);
if (arrCandidate.reduce(function(p, c){ return p + c; }) < 100)
ps.push(arrCandidate);
}
}
return ps;
}
function powersetSums(arr) {
var ps = [[]];
ps[0].sum = 0;
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
var arrCandidate = ps[j].concat(arr[i]);
var sum = ps[j].sum + arr[i]
if (sum < 100) { //don't include this check if negative numbers are allowed
arrCandidate.sum = sum;
ps.push(arrCandidate);
}
}
}
return ps;
}
function splitPowersetLt100(arr) {
var mid = arr.length / 2;
var arr1 = arr.slice(0, mid)
var arr2 = arr.slice(mid, arr.length)
var ps1 = powersetSum(arr1)
var ps2 = powersetSum(arr2)
ps1.sort(function(b,a){return a.sum-b.sum;});
ps2.sort(function(a,b){return a.sum-b.sum;});
var pos1 = 0;
var pos2 = -1;
var result = [[]];
while (pos1 < ps1.length) {
var arr1 = ps1[pos1];
while (pos2 + 1 < ps2.length && ps2[pos2+1].sum+arr1.sum < 100) {
pos2++;
}
for (var i = pos2; i >= 0; i--) {
result.push(arr1.concat(ps2[i]));
}
pos1++;
}
return result;
}
console.log("Starting");
var v1Time = 0;
var v2Time = 0;
var arrs = 100;
var iters = 10;
for (var a = 0; a < arrs; a++) {
if (arrs <= 50) console.log("Round " + a);
var len = 30
var arr = new Array(len);
for (var i = 0; i < len; i++) {
arr[i] = Math.floor(Math.random()*100); //Change this to "1" to simulate the worst case
}
if (a == 0) {
var start = new Date().getTime();
powersetSums(arr);
var end = new Date().getTime();
if ((end - start) * arrs * iters > 20000) { //don't freeze the browser for...