|
Помогите написать числовую функцию
Здравствуйте господа программисты!
Помогите пожалуйста. Необходимо написать функцию деления числа "A" на несколько случайных, сумма которых в итоге будет числом "A". Функция должна иметь 3 параметра, первый это число "A", второе - на сколько частей нужно разбить первое и третье - минимальное значение каждого из чисел. Например: A = 130 получаем 3 случайных числа, кадое из которых больше 20 57, 32, 41 - сумма равна первому число Если идея понятна выслушаю предложения и идеи, как это можно реализовать, если кому будет не сложно приму готовое решение. Заранее благодарен за помощь! |
function funk(a, b, c){
var part = a/b;
var q = 0
for (i=0; i<b-1; i++){
var number = []
number[i] = Math.floor(Math.random()*part)
while(number[i] <= c){
number[i] = Math.floor(Math.random()*part)
}
q= q+number[i]
var lastnam = a - q
alert(number[i])
}
alert(lastnam)
}
Можно так, но это не совсем честный вариант, так как последнее число не случайное. |
PashPP,
предложу свой вариант (последние число почти случайное)
function Num(num, kol, min){
if ((kol * min) > num){
alert("Некорректно введены данные");
return;
}
var kol2 = 0;
var ar = [];
var obh = num - kol * min;
for (var i = 0; i < kol; i++){
ar[i] = min + Math.round(Math.random() * obh);
kol2 += ar[i];
}
if (kol2 > num){
Num(num, kol, min);
return;
}
if (kol2 < num) ar[i - 1] += num - kol2;
alert(ar);
}
Num(130, 3, 20)
|
ashPP, спасибо, вариант интересный, но много в нем не понятного и последнее число всегда больше предыдущих.
|
в идеале все должно быть так, но на деле часто виснет
function funk(a, b, c){
var part = a-((b-1)*c);
var q = 0
for (i=1; i<b; i++){
var number = []
number[i] = Math.floor(Math.random()*part)
while(number[i] <= c){
number[i] = Math.floor(Math.random()*part)
}
q= q+number[i]
part = a - q - (b-i-1)*c
var lastnam = a - q
alert(number[i])
}
alert(lastnam)
}
funk(90, 3, 5)
Высчитываем первоначальное максимальное значение числа a-((b-1)*c). Где а- число, б - количество частей. с - мин. значение части = part. По ходу выпадания чисел part корректируется в зависимости от выпавших перед ним значений part = a - q - (b-i-1)*c . Где q - cумма всех предыдущих выпаданий чисел. Мне просто интересно, насколько верен мой подход с программной точки зрения, не разбираюсь еще в этих материях. |
Dim@,
var obh = num - kol * min; должно же быть var obh = num - (kol -1)* min; Не? |
Dim@,
А, нет, извини. Эт оя не понял, что ты делал. |
Всем спасибо за помощь, предпоследний вариант переделал под свой лад, все работает на ура!
|
Вот моё решение, в котором все возможности выпадают с одинаковой вероятностью.
function divide(a, n, m) {
if (n*m>a)
return;
var b=[], d=[], p=a-(m-1)*n-1;
for (var i=0; i<p; i++)
b[i]=i; // делаем массив b из чисел 0, 1, ..., p-1
for (; i>a-m*n; i--) {
var c=Math.floor(Math.random()*i); // выбираем случайный элемент из b
d.push(b[c]);
b[c]=b[i-1]; // удаляем его, считаем, что длина массива b теперь i-1
}
d.sort(function (x, y) {
return x-y;
});
d.push(p); // после этой инструкции массив d будет содержать n различных неотрицательных чисел, отсортированных по возрастанию, последнее из которых p. С помощью этого массива формируется выходной массив, для которого будем использовать переменную b заново
b.length=0;
b[0]=d[0]+m;
for (i=0; i<n-1; i++)
b.push(d[i+1]-d[i]+m-1);
return b;
}
alert(divide(130, 3, 20));
Ред. Упс, где-то ошибка, выпало 70, -22, 82. Сейчас попробую исправить. Ред. Уже исправил. Оказывается, метод sort, если не задана сравнительная функция, сортирует элементы как строки. |
Прикольная задачка. Предыдущие ответы не читал, ибо лень. :p
// предполагается, что все аргументы - целые неотрицательные числа
function SplitNum (sum, summands, min) {
if (summands < 1 || summands * min > sum) {
return []; // если операцию выполнить невозможно, возвращаем пустой массив
}
var i;
var range = sum - summands * min; // сумма слагаемых после вычета минимумов
var points = []; // здесь будут точки деления диапазона [0; range]
for (i=0; i<summands-1; i++) { // произвольных точек деления на 1 меньше, чем слагаемых
// генерируем псевдослучайное целое число в диапазоне [0; range]
points[i] = Math.floor(Math.random() * (range + 1));
}
points.push(0, range); // добавляем стартовую и конечную точки деления
points.sort(function (a, b) { return a - b; }); // сортируем по возрастанию
var result = []; // сюда будем сгребать слагаемые
for (i=0; i<summands; i++) {
// слагаемое вычисляем по разнице между точками деления с добавлением минимума
result[i] = points[i+1] - points[i] + min;
}
return result; // возвращаем массив слагаемых
}
var text = "";
text += SplitNum(130, 3, 20) + "\n";
text += SplitNum(130, 3, 0) + "\n";
text += SplitNum(130, 1, 20) + "\n";
text += SplitNum(100, 10, 10) + "\n";
text += SplitNum(100, 4, 24) + "\n";
text += SplitNum(100500, 10, 10000);
alert(text);
UPD: oneguy опередил меня, потому что комменты зажопил.)) Хотя наши решения немножко отличаются. :) |
| Часовой пояс GMT +3, время: 20:56. |
|