Задачка по генерации чисел
Приветствую! Помогите решить задачку на генерацию чисел.
Примерно понимаю, нужно в цикле пустить 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, время: 15:56. |