массив со случайными числами
Помогите создать массив c четырьмя числами. Одно число известное, три случайных в пределах от 0 до n. Ни одно из трех случайных чисел не должно быть равно известному.
И порядок всех четырех чисел в массиве должен быть случайным. p.s. Ни одно число в массиве не должно повторятся |
function rand(val,max){
var arr = [],
i = 3,
pos = Math.floor(Math.random()*(i+1));
while(i--){
var rnd = Math.floor(Math.random()*max);
arr.push(rnd >= val ? ++rnd : rnd);
}
arr.splice(pos,0,val);
return arr
}
alert(rand(3,5))
|
спасибо
Работает но я еще забыл упомянуть что ни одно число не должно повторяться |
Цитата:
var num = 5;
var arr = [num];
var n = 10;
for(var i = 0; i < 3; i++) {
do {
var randNum = Math.round( -0.5 + Math.random()*(n+1) );
} while( arr.indexOf(randNum) !== -1);
arr.push(randNum);
}
arr.sort(function(){ return Math.random()-0.5 });
alert(arr);
|
jsnb, ужасно, даже чудовищно. Так делать нельзя никогда.
Конечно на конкретной задаче с массивом из 4 чисел вся мерзость заметна не будет, но за такой код я бы клаву об голову разбил, да. |
Цитата:
|
И в сортировке - ибо она псевдорандомна и не даёт нормального распределения, и в потенциальном вечном(очень долгом) цикле бессмысленного брутфорса.
Как? Ответ в моём решении например, если его расширить. |
Цитата:
|
Вот функция:
function rand(max, min, length){
var result = [],
resultSorted = [];
if(typeof max !== 'number') return Math.random();
if(typeof min !== 'number') return Math.floor(Math.random() * ++max);
if(min > max) min = [max, max = min][0];
if(!length || typeof length !== 'number') return Math.floor(Math.random() * (max - min + 1)) + min;
if(length > max - min + 1) throw new RangeError('invalid length.');
for(var j = 0, random, index; j < length; j++, max--){
random = Math.floor(Math.random() * (max - min + 1)) + min;
for(index = j; index && resultSorted[index-1] <= random; index--) random++;
result.push(random);
resultSorted.splice(index, 0, random);
}
return result;
}
Генерирует массив не повторяющихся рандомных чисел из заданного диапазона заданной длины. Кое что ещё можно пооптимизировать, но суть должна быть понятна. |
:write:
ещё вариант ... без проверки входных данных
function rand(val, min, max, length) {
var obj = {}, arr = [val];
obj[val] = true;
length--;
while (length) {
var rnd = Math.floor(Math.random() * (max - min + 1)) + min;
if (!obj[rnd]) {
obj[rnd] = true;
length--;
arr[Math.random() > .5 ? 'push' : 'unshift'](rnd)
};
}
return arr
}
alert(rand(3, 7, 12, 4))
|
рони, то же что у jsnb, только в профиль. Опять потенциально бесконечный цикл, при неудачном рандоме. И чем массив долинее тем шансы на это больше.
|
Aetae, а если так оформить рендом.... все равно может в бесконечность уйти ?
var random = Math.round(min - 0.5 + Math.random()*(max-min+1)); |
Aetae,
:)
<script language="JavaScript" type="text/javascript">
function random(val,min,max,l)
{var arr = [],m = [],n = void(0), len = max-min;
l--;
if (len < l) return;
for (var i=0; i<= len; i++){
m[i] = i + min;
m[i] == val && (n = i);
}
n != void(0) && m.splice(n,1)
for (var i=0; i<l; i++) {n = Math.floor(Math.random()*(m.length)); arr[i]=m.splice(n,1);};
n = Math.floor(Math.random()*(arr.length));
arr.splice(n,0,val)
return arr
}
document.write(random(3,0,20,4))
</script>
источник ))) |
рони, вот, другое дело. Кончено при слишком большом диапазоне в памяти будет висеть гигантский массив, и я всё ещё считаю свой вариант лучше, но хоть так.)
|
Цитата:
Цитата:
|
рони,
Пока есть среди уже подобранных(и отсортированных) числа меньше или равные числу сгенерированному на текущей итерации - инкрементируем оное. Т.о. не допускается повторов, и при этом соблюдается нормальное распределение. В моём коде две проблемы: наличие дублирующего, но отсортированного массива и использование условно-медленного splice. |
| Часовой пояс GMT +3, время: 02:13. |