Home > Blockchain >  Divide a number into n unequal parts
Divide a number into n unequal parts

Time:01-07

I have a number N e.g. 100 and I want to divide it into n parts (e.g. 10 parts)

Doing this linearly is trivial - N/n and I get 10 parts each of the value 10.

However, I would like to do this so that the parts are unequal and increase exponentially. E.g.

10, 30, 60 so the total is 100.

How can I write this as a javascript function?

function returnParts(desiredTotal, numParts) {
    ...
    return parts ///return an array of parts
}

CodePudding user response:

This is a Math problem. Once you solve it, implementing this with JS or any other language is just calculation.

So you want K numbers summing to T. However they will increase exponentially. Not so clear but from your given example lets assume our exponential series to be

T = x   2x   4x   8x   ...   2^(n-1) x

We can apply summing series trick here like

2T = 2x   4x   8x   ...   2^n x

Now;

   2T = 2x   4x   8x   ...   2^x
    T =  x   2x   4x   8x   ...   2^(n-1) x
(-)__________________________________
    T = 2^n x - x = (2^n - 1) x

So;

        T
x = _________
     2^n - 1

The JS part.

function part(n,target){
  var x = target / (2**n-1);
  return Array.from({length:n}, (_,i) => x*2**i);
}

var result = part(6,100),
    sum    = result.reduce((p,c) => p c);

console.log(result,sum);

CodePudding user response:

The function is simple enough, when you allow floating point numbers:

function getNums(n,f,tot){
let x=1;
 const arr=[...new Array(n)]
  .map(c=>x*=f);
 const mul=tot/arr.reduce((a,c)=>a c);
 return arr.map(v=>mul*v)
}
 
console.log(getNums(3, 1.5, 100))

In order to get a unique result you need to specify the desired count n of numbers, the factor between the numbers f and the total tot the individual numbers must add up to.

And here is an adapted solution for integers:

function getNums(n,f,tot){
let x=1,res;
 const arr=[...new Array(n)]
  .map(c=>x*=f);
 const mul=tot/arr.reduce((a,c)=>a c);
 
 res=arr.map(v=>Math.round(mul*v));
 res[res.length-1]-=res.reduce((a,c)=>a c)-tot;
 return res

}
const ar=getNums(3, 1.5, 100);
console.log(ar,ar.reduce((a,c)=>a c))

CodePudding user response:

This should do it. The exponential function is: A^numParts = desiredTotal. We first solve for A then push the values calculated values into the array. This works because the integral of an exponential function is the exponential function.

function returnParts (desiredTotal, numParts) {
  var a = Math.pow(desiredTotal, 1/numParts)
  var parts = []
  for (var j = 0; j < numParts; j  ) {
    var part = Math.pow(a, j   1) - Math.pow(a, j)
    parts.push(part)
  }
  return parts
}

For example:


var results = returnParts(1000, 3)
console.log(results)
//
//returns [9.999999999999998, 89.99999999999997, 909.9999999999994]
// which is equal to ~1000
// 


  •  Tags:  
  • Related