Erlend Westbye
Erlend Westbye

Reputation: 53

Generating alphanumerical sequence javascript

I have written a terribly slow function for generating codes that go from AA000 to ZZ999 (in sequence not random). And I have concluded that there has to be a better way to do this. Any suggestions on how to make this faster?

function generateAlphaNumeric(){

theAlphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
resultArrray = [];
resultArrray2 = [];
teller = 0;

for(i in theAlphabet){
    for(x in theAlphabet){
        resultArrray[teller] = theAlphabet[i] + theAlphabet[x];
        teller++;
    }
}
teller = 0;
for(x = 0; x<10; x++){
    for(y = 0; y<10; y++){
        for(z = 0; z<10; z++){
            resultArrray2[teller] = x.toString() + y.toString() +z.toString();
            teller++;
        }
    }
}
teller = 0;
finalArray = [];
for(index in resultArrray){
    for(i in resultArrray2){
        finalArray[teller] = resultArrray[index] + resultArrray2[i];
        teller++;
    }
}
//console.log(resultArrray);
//console.log(resultArrray2);
console.log(finalArray);
}

Upvotes: 5

Views: 161

Answers (5)

lex82
lex82

Reputation: 11317

This should be considerably faster:

var theAlphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W','X','Y','Z'];
var theDigits = ['0','1','2','3','4','5','6','7','8','9'];

var result = [];
for (var i=0 ; i<26 ; i++) {
    var prefix1 = theAlphabet[i];
    for (var j=0 ; j<26; j++) {
        var prefix2 = prefix1 + theAlphabet[j];
        for(var x = 0; x<10; x++){
            var prefix3 = prefix2 + theDigits[x];
            for(var y = 0; y<10; y++){
                var prefix4 = prefix3 + theDigits[y];
                for(var z = 0; z<10; z++){
                   result.push(prefix4 + theDigits[z]);
                }
            }       
        }
    }
}

Key ideas:

  • Generate everything in one run
  • Reuse partial strings as much as possible

However, I don't see how such an exhaustive list is useful. There are exactly 26 * 26 * 1000 different codes. So instead of maintaining an array with all codes it could make sense to simply build a function that generates the specific code requested:

function getCode(number) {
    var z = number % 10;
    number -= z; number /= 10;
    var y = number % 10;
    number -= y; number /= 10;
    var x = number % 10;
    number -= x; number /= 10;
    var a = number % 26;
    number -= a; number /= 26;
    var b = number;

    return theAlphabet[a] + theAlphabet[b] + theDigits[x] + theDigits[y] + theDigits[z];
}

Upvotes: 3

Arun Vijayvergiya
Arun Vijayvergiya

Reputation: 1

From a computational complexity perspective, unfortunately this is the best you can do. From a sheer number of instructions perspective, you can do a bit better (as others have pointed out), but it's still going to be the same order of complexity (remember that constants / multipliers are irrelevant in big-O complexity). You can also optimize the storage a bit.

Think about it. Your array needs to have 26 * 26 * 10 * 10 * 10 members. This means you need to at least touch that many elements.

Let N = number of elements in the alphabet Let M = number of elements in your digit queue

Best Case Order Complexity = O(N * N * M * M * M) (if all you had to do was assign values)

Best case storage complexity = same as above (you have to store all the codes)

Right now you are using the following operations:

for(i in theAlphabet){ // *O(N)*
  for(x in theAlphabet){ // *O(N)*
    resultArrray[teller] = theAlphabet[i] + theAlphabet[x];// *(O(1))*
  }
}



for(x = 0; x<10; x++){ // O(M)
    for(y = 0; y<10; y++){ // O(M)
        for(z = 0; z<10; z++){ // O(M)
            resultArrray2[teller] = x.toString() + y.toString() +z.toString(); // O(1) (technically this is O(length of x + y + z)
            teller++;
        }
    }
}


for(index in resultArrray){ // O(N * N)
    for(i in resultArrray2){ // O(M * M * M(
        finalArray[teller] = resultArrray[index] + resultArrray2[i]; //O(1)
        teller++;
    }
}

So at the end of the day your order complexity is O(N * N * M * M * M), which is the best you can do.

The bigger question is why you want to generate all the codes at all. If all you want is to create a unique code per order number or something, you can make a state machine like:

function getNextCode(previousCode) {
   // in here, just increment the previous code
}

If all you want is a random identifier, consider using a hash of the timestamp + something about the request instead.

If you don't care about uniqueness, you can always just generate a random code.

All of the above are O(1).

Upvotes: 0

MrPanda
MrPanda

Reputation: 99

I didn't test it, but it should do the trick

function generateAlphaNumeric()
{

   var theAlphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
   var result = [];

   // Will take a random letter inside theAlphabet
   // Math.floor(Math.random() * theAlphabet.length) will  generate a random number between 0 and 25
   var i = 0;
   while(i<2)
   {
      var letter = theAlphabet[Math.floor(Math.random() * theAlphabet.length)];
      result.push(letter);
      i++;
   }

   i = 0;
   while(i<3)
   {
      // Adds a random number between 0 and 9
      result.push(Math.floor(Math.random() * 10));
      i++;
   }
   return result;
}

Upvotes: 0

Dmitri Pavlutin
Dmitri Pavlutin

Reputation: 19090

Try this solution:

  function generate() {
    var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
        ar = [];
    for (var index1 = 0; index1 < str.length; index1++) {
      for (var index2 = 0; index2 < str.length; index2++) {
        for (var index3 = 0; index3 < 1000; index3++) {
          ar.push(str[index1] + str[index2] + ('000' + index3).slice(-3));
        }
      }
    }
    return ar;
  }
  console.log(generate());

Upvotes: 0

Satyam S
Satyam S

Reputation: 267

function generate() {
    var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
        array = [];
    for (var i = 0; i < str.length; i++) {
      for (var j = 0; j < str.length; j++) {
        for (var k = 0; k < 10; k++) {
          for (var l = 0; l < 10; l++) {
            for (var m = 0; m < 10; m++) {
              ar.push(str[i] + str[j] + k + l + m);
            }
          }
        }
      }
    }
    return array;
  }
  console.log(generate());

This will generate a array of all the codes .. U can save that array and parse it easily using a loop.

Upvotes: 0

Related Questions