A
A
Alexey2018-09-16 01:29:23
JavaScript
Alexey, 2018-09-16 01:29:23

Which Node.js library can be used for uniform division?

Hello!
I do not know how to express it correctly "in mathematical terms")
The essence of the problem is as follows.
- there is some (generally) real number
- there is an integer - number of partitions
- there is some limitation - accuracy
Need to find a "uniform" partition
Easier to show by example
Initial number - 20, number of partitions - 3, accuracy of partitions - to an integer
The appropriate result is 6-7-7 (three integers, summing up to the original). Variants like 5-7-8 will not work - their spread is not quite "uniform"
It is clear that, for example, the number 18 is divided into three "uniform" partitions without problems - 6-6-6
A more complex example
The original number is 27.8, the number of partitions is 4, the accuracy is 0.1. A suitable result is 6.9-6.9-7.0-7.0
Precision is not the maximum allowable deviation between the received numbers, but the maximum (minimum?) accuracy of the numbers themselves. That is, with an accuracy of 0.1, there cannot be a number, for example, 2.75 - only 2.7 or 2.8
. I suspect that this problem probably has its own name and, accordingly, the calculation algorithm. I would be glad if someone shares it, but ideally I would like a ready-made solution on Node.js
Thanks in advance for the answers

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
index0h, 2018-09-16
@amexlar

Quite an interesting task, here of course you still need to do a bunch of checks, but the algorithm may look something like this: https://3v4l.org/DQRKq

S
Sergey Sokolov, 2018-09-16
@sergiks

Can be solved with recursion.
At each step, we get the next term, rounding the result to the nearest one in the “grid”, taking into account the accuracy. For integers it looks like this:

Math.round(20 / 3) === 7 // 7 занесли в массив результата
20 - 7 = 13 
// далее повторяем с 13 и делим уже на 3 - 1 === 2
Math.round(13 / 2) === 7 // 7 идёт в результат
13 - 7 === 6
// далее повторяем с 6 и делить надо бы на 2 - 1 === 1
// т.е. осталось одно число в результат. Просто вписываем туда остаток 6

Precision must be multiplied/divided by that precision before rounding to the nearest integer. But here problems with accuracy of a floating point get out. Therefore, it is necessary to clarify what the accuracy values ​​\u200b\u200bcan be: up to def. decimal point, or any value of type 0.137456?
function split(n, divisor, q, result) {
  q = q || 1;
  result = result || [];
  const m = q * Math.round(n / divisor / q);
  result.push(m);
  n -= m;
  if( --divisor > 1) return split(n, divisor, q, result);
  else {
    result.push(n);
    return result.sort((a,b) => a - b); // сортировка по возрастанию, на всякий случай
  }
}


split(20, 3) // [6, 7, 7]
split(20, 3, 0.1) // [6.6000000000000005, 6.7, 6.7]
split(27.8, 4, 0.1) // [6.9, 6.9, 7, 7]

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question