Задачка по генерации чисел
Приветствую! Помогите решить задачку на генерацию чисел.
Примерно понимаю, нужно в цикле пустить Math.random Нужно сгенерировать набор из 20ти цифр (без пробелов), пример (для наглядности с пробелами): 2 10 19 15 8 0 3 5 11 17 2 1 2 0 1 0 2 1 0 2 Структура: первые 10 цифр от 0 до 19 (повторяться запрещено), следующие 10 цифр от 0 до 2 |
var data = new Array(20),
i = 0, n;
function getRandomInt(n) {
return Math.floor(Math.random() * ++n);
}
while(i < 10) {
n = getRandomInt(19);
if(data.indexOf(n) < 0) {
data[i] = n;
data[i + 10] = getRandomInt(2);
i++;
}
}
alert( data );
alert( data.join('') );
|
function indexRandom(lng){
var a = {},i,out=[],n=0;
while (n!=lng){
i = Math.floor(lng*Math.random());
if(typeof(a[i])=='undefined'){
a[i]=i; out.push(i);
n++;
}
}
return out;
}
var arr = [],ind = indexRandom(20),k;
for(i=0;i<20;i++) arr[i]=ind[i]%(k=i<10?20:3);
alert(arr)
alert(arr.join(''))
|
Deff, 3 цикла? :blink:
|
Спасибо, сейчас попробую) Я тоже начал, уже практически закончил, но косячнул видимо на проверке повторяющихся числе в первой десятке (повторяющиеся числа остаются).
//Функция генерации
function randomInteger(min, max) {
var rand = min - 0.5 + Math.random() * (max - min + 1)
rand = Math.round(rand);
return rand;
}
//Создаём массив
var numb = [];
//Начинаем заполнять массив
for (i=0;i<=19;i++) {
//Пошла первая десятка
if (i < 10) {
var my_numb = randomInteger(0, 19);
numb[i] = my_numb;
if (i > 0) {
//Функция проверки повторов
check_numb()
function check_numb() {
for (l=0;l<=i-1;l++) {
if (numb[l] == my_numb) {
alert(my_numb)
numb[l] = randomInteger(0, 19);
check_numb()
}
}
}
}
}
//Пошла вторая десятка
if (i > 9) {
numb[i] = randomInteger(0, 2)
}
}
alert(numb.join(''));
|
Спасибо, всё работает у вас.
Я побыдлокодил конечно, но действовал исходя из логики и недостатка знаний) |
:) random только 20 раз и никаких повторов :dance:
<script>
Array.prototype.shuffle = function() {
for (var a = this.length; 0 <= a; a--) {
var b = Math.floor(Math.random() * (10 > a ? 3 : a + 1)),
c = 10 > a || void 0 === this[b] ? b : this[b];
10 < a && (this[b] = void 0 === this[a] ? a : this[a]);
this[a] = c
}
return this.reverse()
};
var arr = new Array(20).shuffle();
document.write(arr+"<br>"+arr.join(''))
</script>
|
рони, ++
Да, скоростью я был удивлён еще в табличке ================ Вариант рандомного массива без повторений с вызовом Math.random() единожды на каждый элемент:
function indRand(lng){
var a = [],i,out=[],n=lng;
for(i=0;i<lng;i++)a[i]=i;
while (n--)out.push(a.splice(Math.floor((n+1)*Math.random()),1)[0]);
return out;
}
var arr = [],ind = indRand(20),k;
for(i=0;i<20;i++) arr[i]=ind[i]%(k=i<10?20:3);
alert(arr)
alert(arr.join(''))
|
Deff,
на всякий случай, надобы поправить indRand, когда-то я сам прокололся на таком использовании splice :cray: |
рони,
Если массив создаешь внутри функции, вроде как фичи нет,... А вообще интересно, как оно обходит созданные прототипы и выходит на начальный родитель(ксать можно использовать(Это если массив передаём в функцию) Или ты не об этом ? Тады ап чём ? |
Ув. рони,
Ув. Deff, объясните пожалуйста чем плох код, предложенный Ruslan_xDD в этом посте? То, что он предложил легко читается и очевидное решение. А ваши решения выглядят со стороны как навороты. Только без обид. Просто любопытно |
Цитата:
Автор уже доволен, но применяемый код мон вылизать. Где-то был даж спец. топик с такими скриптами-задачками ================================== К примеру у нас с Рони как то была задача протестить код на миллионе повторов. При неотлизанном коде - это часы... К примеру тот жа Math.random() на массиве в 10 элементов вызывается средне=статистически при таких функциях неповторяющейся выборки 29 раз - на 20 - 70 при дальнейшем увеличении массива растёт в какой-то степени(посколь попадает в уже выбранные значения) Т.е. время на коротких массивах растёт вдвое-втрое |
Цитата:
|
Цитата:
====================== |
EmperioAf,
код Ruslan_xDD генерирует числа Math.random более 20 раз чтоб избежать повторов, мой код генерирует только 20 раз и без повторов. |
Deff,
в консоли посмотри :) |
рони,
Ок :( ================
// Тест средне-статистического числа повторов Math.random() на создание неповторяющегося массива из 1000 элементов
function indexRandom(lng){
var numRnd = 0;
var a = {},i,out=[],n=0;
while (n!=lng){
i = Math.floor(lng*Math.random()); numRnd++;
if(typeof(a[i])=='undefined'){
a[i]=i; out.push(i);
n++;
}
}
return numRnd;
}
function repeat(n){
var N=0;n2=n
while (--n2){
N+= indexRandom(1000);
}
return N/n;
}
alert('N='+repeat(10000))
// Тест средне-статистического числа повторов Math.random() на создание неповторяющегося массива из 20 элементов
function indexRandom(lng){
var numRnd = 0;
var a = {},i,out=[],n=0;
while (n!=lng){
i = Math.floor(lng*Math.random()); numRnd++;
if(typeof(a[i])=='undefined'){
a[i]=i; out.push(i);
n++;
}
}
return numRnd;
}
function repeat(n){
var N=0;n2=n
while (--n2){
N+= indexRandom(20);
}
return N/n;
}
alert('N='+repeat(10000))
// Тест средне-статистического числа повторов Math.random() на создание неповторяющегося массива из 10 элементов
function indexRandom(lng){
var numRnd = 0;
var a = {},i,out=[],n=0;
while (n!=lng){
i = Math.floor(lng*Math.random()); numRnd++;
if(typeof(a[i])=='undefined'){
a[i]=i; out.push(i);
n++;
}
}
return numRnd;
}
function repeat(n){
var N=0;n2=n
while (--n2){
N+= indexRandom(10);
}
return N/n;
}
alert('N='+repeat(10000))
======================= Зы: Примерная апроксимация кол-ва обращений к Math.random() по четырём точкам: n - длина массива x = n+n^1.26 |
Цитата:
|
рони,
СПС, - я понял, тут отвлекают(отхожу от компа + возгорелся протестить: А скок реально рандомов лишних ? ) поэтому долго с правкой того поста |
рони,
А эту феньку видел ?
function abc(arr){
var a = arr.splice(0,3);
}
var arr = [1,2,3];
abc(arr);
alert('>'+arr+'<')
function abc(arr){
function abcd(ar2){
var a = ar2.splice(0,3);
}
abcd(arr)
}
var arr = [1,2,3];
abc(arr);
alert('>'+arr+'<')
function abc(arr){
arr=[];
}
var arr = [1,2,3];
abc(arr);
alert('>'+arr+'<')
|
Создание массива с уникальными данными и в указанном диапазоне
функция заполняет массив уникальными данными в указанном диапазоне или перемешивает исходный, если диапазон не указан заполняет от нуля по порядку.
в трёх примерах ниже генерация происходит только пять раз.(исходная длина массива)
<script>
Array.prototype.randomShuffle = function(min,max) {
min = min || 0;
max = ++max || this.length;
var len = max - min;
max = len - this.length;
this.length = len;
for (var a = this.length-1; 0 <= a; a--) {
if(a < max) {break}
var b = Math.floor(Math.random() * a),
c = void 0 === this[b] ? (b + min) : this[b];
this[b] = void 0 === this[a] ? (a + min) : this[a];
this[a] = c
}
this.reverse();
this.length -= max;
return this
};
var arr = Array(5).randomShuffle();
document.write(arr+"<br>")
var arr = Array(5).randomShuffle(-100,100);
document.write(arr+"<br>")
var arr =[1,2,3,4,5].randomShuffle();
document.write(arr+"<br>")
document.write(["Собака след не взяла, Взяла", "но была убита убегающим", "след потеряла"].randomShuffle()+"<br>")
</script>
|
Deff,
не осилил |
Deff,
ок, ничего не мешает вынести предложенный метод из прототипа в отдельную функцию, но меня твои аргументы не убедили, по моему проще если нужно сделать arr.slice().shuffle() чем slice добавлять в функцию. |
function indRand(a){
var out=[],n=a.length; a=a.slice(0);
while (n--){out.push(a.splice(Math.floor((n+1)*Math.random()),1)[0]);}
return out;
}
var tim = +new Date
var arr='1234567890'.split('');
n=1000000;
while (n--){
var b = indRand(arr);
}
alert((+new Date-tim)/1000);
Array.prototype.shuffle = function(min,max) {
min = min || 0;
max = ++max || this.length;
var len = max - min;
max = len - this.length;
this.length = len;
for (var a = this.length-1; 0 <= a; a--) {
if(a < max) {break}
var b = Math.floor(Math.random() * a),
c = void 0 === this[b] ? (b + min) : this[b];
this[b] = void 0 === this[a] ? (a + min) : this[a];
this[a] = c
}
this.reverse();
this.length -= max;
return this
};
var tim = +new Date
var arr='1234567890'.split('');
n=1000000;
while (n--){
var arr =arr.shuffle();
}
alert((+new Date-tim)/1000);
Твой Вариант значительно быстрее! Гы, а на длинных массивах, длиной более 100, преимущество в 8 и более раз! :dance: |
Ксать подобная перестановка в математике обзывается
randomShuffle (Имхо более говорящее название, нативный перевод как: случайная перестановка из массива существующих) ============================== Выложил бы на Хабре - Фишка весьма востребованная ( к примеру для массовой генерации паролей или ключей (Видел сотни вопросов про как сделать - всё примерно делали как в посте от Ruslan_xDD... Упор делать на "быстрая!" . |
Deff,
randomShuffle ок :)
Array.prototype.randomShuffle = function(c, b) {
c = c || 0;
b = ++b || this.length;
var a = b - c;
b = a - this.length;
this.length = a;
for (a = this.length - 1; 0 <= a && !(a < b); a--) {
var d = Math.floor(Math.random() * a),
e = void 0 === this[d] ? d + c : this[d];
this[d] = void 0 === this[a] ? a + c : this[a];
this[a] = e
}
this.reverse();
this.length -= b;
return this
};
alert(Array(5).randomShuffle())
|
Посмотри такой нюанс при max<2
var arr = Array(5).shuffle(-1,1); Либо нун пояснить про диапазон c, b |
Deff,
защиты от дурака я не встраивал :) |
:write:
чуть сократил ещё :)
Array.prototype.randomShuffle = function(c, b) {
c = c || 0;
b = ++b || this.length;
var a = b - c;
b = a - this.length;
this.length = a--;
for (; 0 <= a && !(a < b); a--) {
var d = Math.floor(Math.random() * a),
e = void 0 === this[d] ? d + c : this[d];
this[d] = void 0 === this[a] ? a + c : this[a];
this[a] = e
}
this.reverse();
this.length -= b;
return this
};
alert( Array(5).randomShuffle(-1,1))//заполнение пустого массива идёт на длину указанного диапазона от min до max
alert( Array(5).randomShuffle(-10,10))
|
рони, Т.е, если массив длинной 5, разность мин-мах диапазона проставленного в параметрах [a,b] вызова метода randomShuffle(a,b) должна быть не меньше пяти, для полного заполнения массива уникальными значениями ( Я задаю типовые вопросы, согласно любому представления нового скрипта на Хабре, вот я ап чём) Для тренировки :yes:
|
Deff,
да :) и min < max |
:) Нашел готовую решабелку по судоку, единственное оформить поудобнее-посимпатичней
|
| Часовой пояс GMT +3, время: 04:47. |