将一个数分成n个不相等的部分

Divide a number into n unequal parts

我有一个号码 N 例如100,我想把它分成n份(比如10份)

线性执行此操作很简单 - N/n 我得到 10 个部分,每个部分的值为 10。

但是,我想这样做,使部分不相等并呈指数增长。例如

10、30、60 所以总数是 100。

如何将其写成 javascript 函数?

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

函数很简单,当你允许浮点数时:

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))

为了获得唯一的结果,您需要指定所需的数字计数 n,数字 f 与各个数字的总数 tot 之间的因数必须相加最多。

这里是一个适用于整数的解决方案:

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))

@Redu 提供了一个公式,用于计算 2**i 系列的总和 for n values 。通过使用一般年金公式,您会发现一个合适的起始值x可以通过以下等式计算:

当我应用这个公式时,我可以在我的脚本中保存一些计算:

// small utility function
function sum(a,c){return a+c}

// create a series of n integers with 
// factor b between them, having a total sum of tot:
function numSeries(b,n,tot){
 let x=tot*(1-1/b)/(b**n-1)

 const ar=[...new Array(n)]
  .map(_=>Math.round(x*=b) );
  // adjust the last number for rounding errors:
 ar[n-1]=tot-ar.slice(0,-1).reduce(sum);
 return ar;
}

// test it all:
const ar=numSeries(1.75,7,200);
console.log(ar,ar.reduce(sum))

这是一道数学题。一旦你解决了,用JS或其他任何语言实现它只是计算。

因此您希望 K 个数字的总和为 T。但是它们会呈指数增长。不太清楚,但从你给出的例子让我们假设我们的指数级数是

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

我们可以在这里应用求和级数技巧,例如

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

现在;

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

所以;

        T
x = _________
     2^n - 1

JS部分。

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);

这应该可以做到。指数函数是:A^numParts = desiredTotal。我们首先求解 A,然后将计算出的值推入数组。这是有效的,因为指数函数的积分是指数函数。

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
}

例如:


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