0

My goal is to create a 2D Array, and assign a unique number from 0 to n for each in Javascript.

For example, if there is 5 rows and 5 cols, I first make an array of values containing the numbers from 0 to 24. I then want to shuffle those numbers and then if the number is less than 10, place a 'Y' for that spot in the Array or a 'N' if it's greater than or equal to 10. The end result should be 15 N's and 10 Y's randomly located.

I have the following code that does that, but I find it really inefficient and was wondering if there was a better way of doing it.

//Define Empty Array
test = new Array(rows);

for (var k = 0; k < rows; k++)
{
    test[k] = Array(cols);
}


var values = [];
var index = 0;
var maxVals = (rows * cols);

//If maxVals is equal to 25, then the values array will hold "1,2,3,4, ... 24,25"
while(values.push(index++)<maxVals);

//Shuffle all those values so they're no longer in order
var shuffledValues = _.shuffle(values);


var i = 0;
var smallerThan = 10;

for (var x = 0; x < rows; x++)
{
    for (var y = 0; y < cols; y++)
    {

        //Make all the numbers smaller than 10 a Y
        if (shuffledValues[i] < smallerThan)
        {
            test[x][y] = "Y";
        }
        else
        {
            test[x][y] = "N";
        }

        i++;
    }
}
Brendan
  • 175
  • 2
  • 15
  • Does it need to be exactly 10 and 15? Is it always < 10 for "Y"? – mclaassen Aug 06 '14 at 01:40
  • Not always, I made the 10 here a number instead of a variable just to make it easier to understand, but it'll be a variable in the real code. – Brendan Aug 06 '14 at 01:54
  • is there a reason why are you shuffling and then checking the value of the index? could you just create an array of desired Y/N count and then shuffle? – haxxxton Aug 06 '14 at 02:02
  • What would be the best way to create an Array with the desired 'Y'/'N's and then shuffling it so that it really is no longer in any order? Would that be more efficient? – Brendan Aug 06 '14 at 12:20

1 Answers1

1

Since you need to iterate over all n = rows×columns elements in your array to set a value your algorithm already has a minimum time complexity of O(n). The loop that creates the indexes array is another n and the shuffle method (if implemented correctly) should shuffle in n as well, so you algorithm is already O(3n) = O(n). While you may be able to reduce the constant factor of 3 it's not going to make any huge difference as your number of rows and columns grows large.

If you don't need exactly a certain number to be "Y" or "N" and just a ratio of them on average then you could do this instead:

var ratio = 0.5; //use your required ratio here
for (var x = 0; x < rows; x++)
{
    for (var y = 0; y < cols; y++)
    {
        test[x][y] = Math.random() < ratio ? "Y" : "N";
    }
}
mclaassen
  • 4,652
  • 3
  • 27
  • 51
  • Thanks for your answer! I was just wondering though, let's say I do need to have an exact number of 'Y's and 'N's. Would it be good to use your method, and then cycle through the values and turn extra 'Y's into 'N's and extra 'N's into 'Y's until I get the exact desired outcome? Or would another approach be better for this kind of situation? – Brendan Aug 06 '14 at 12:00
  • You would be better off just doing how you are doing it already. You might be able to save a little time by just filling an array with the appropriate number of Ys and Ns and then just shuffling that though. Its still going to have to loop 3 times over rows*columns number of elements but you will at least eliminate the if statements in the final loop. See here: http://stackoverflow.com/questions/12503146/create-an-array-with-same-element-repeated-multiple-times-in-javascript – mclaassen Aug 06 '14 at 13:10