3

Is there an efficient way to unwrap an integer into random, unique numbers?

I want 10 to become 3 4 6 1 0 2 5 7 8 9.

I tried THIS ...but before pushing values into arrays and going loop crazy I thought maybe there was a better way.

EDIT:

HERE IS MY NEW FIDDLE AND FUNCTION:

function uniqueDigits(x){
    y = [];
    z = [];
    while(x > 0) {    
        y.push(x);
        x--;
    } 
    while(y.length > 0){
        var r = Math.floor(Math.random()*y.length);
        var u = y[r]
        y.splice(r, 1);
        z.push(u-1);
    }         
    return z;
}

uniqueDigits(4) //['2', '3', '0', '1']

EDIT:

AND HERE IS ANOTHER OPTION:

function uniqueNum(x){
  z = y = x;
  var r = Math.ceil(Math.random() * x);

  while ( x%r%2 == 0 ) {
    r = Math.ceil(Math.random() * x);
  }

  while( x>0 ){
    y = y - r     
    if(y<0){ 
      var n = y; 
      y = z + n 
    }   
    $('p').append(y);
    x--
   }    
} uniqueNum(4);//['2', '3', '0', '1']

OR THIS one too

Ok I'm done.

Squirrl
  • 4,909
  • 9
  • 47
  • 85
  • @WesleyMurch Its not a duplicate of the first one. The output cannot repeat – Squirrl Feb 20 '14 at 09:44
  • It's not a duplicate of the other either, Look this repeats the same integers: http://jsfiddle.net/ecLHN/ – Squirrl Feb 20 '14 at 09:48
  • @Squirrl, are you pressing "Run" repeatedly in jsfiddle? If yes, then of course it can repeat, but it's nothing wrong with the code :-) – Strille Feb 20 '14 at 09:50
  • @Squirrl although your solution can be derived from the linked posts I think your question is unique enough for a tailored answer and have voted to reopen (FYI there are 2 reopen votes at the moment). Sorry to have voted to close so quickly. – Wesley Murch Feb 20 '14 at 09:52
  • Thanks Wesley. I thought perhaps there was a particularly elegant way to solve such a seemingly simple task. – Squirrl Feb 20 '14 at 09:53
  • 1
    for pseudo randomized array (not really random): `var pseudoRandomArray = Array.apply(null, { length: 10 }).map(Number.call, Number).sort(function() { return Math.random() > Math.random(); });` – A. Wolff Feb 20 '14 at 10:07
  • http://jsfiddle.net/aQMFG/ Works. Not sure if it's the best way. – Squirrl Feb 20 '14 at 10:08

3 Answers3

3

Since you are looking for all number in the range, try

var x = 10,
    array = [];
for (var y = 0; y < x; y++) {
    array.push(y);
}
while (array.length) {
    var random = Math.floor(Math.random() * array.length);
    $('p').append(array.splice(random, 1));
}

Demo: Fiddle


Another way using an array is

var x = 10,
    array = [];
//used for counting the loop for performance testing - remove it
var counter = 0;
for (var y = 0; y < x;) {
    var random = Math.floor(Math.random() * x);
    if ($.inArray(random, array) == -1) {
        $('p').append(random);
        array.push(random);
        y++;        
    }
    //for test
    counter++;
}
console.log(counter)

Demo: Fiddle - but the loop executes too many times

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
1

To be more efficient, I would write the range, and then shuffle it like using

The de-facto unbiased shuffle algorithm is the Fisher-Yates (aka Knuth) Shuffle.

from How to randomize (shuffle) a javascript array? answer.

So it would be:

var x = 10;
var range = [];
for (var y = 0; y < x; y++) {
    range.push(y);
}
function shuffle(array) {
  var currentIndex = array.length
    , temporaryValue
    , randomIndex
    ;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
}
shuffle(range);
Community
  • 1
  • 1
Xavier Delamotte
  • 3,519
  • 19
  • 30
0

I would go about it this way:

function getRandomNonRepeatedInt(limit)
{
    var array = [], result = "";
    for (var y = 0; y <= limit-1; array.push(y), y++);
    while (array.length) result = result + array.splice(Math.floor(Math.random() * array.length), 1)[0];
    return result;
}

Sorry about the obfuscation... :-)

Fiddle

Fabricio
  • 839
  • 9
  • 17