0

I'm totally not a Math whiz kid here, but have put together a function with the great help of StackOverflow (and a lot of trial and error) that generates a random serial number from a Formula, group of Letters/Numbers, and array (so as to not duplicate values).

So, my current formula is as follows:

$.extend({
    generateSerial: function(formula, chrs, checks) {
        var formula = formula && formula != "" ? formula : 'XXX-XXX-XXX-XXX-XXX', // Default Formula to use, should change to what's most commonly used!
            chrs = chrs && chrs != "" ? chrs : "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",  // Default characters to randomize, if not defined!
            len = (formula.match(/X/g) || []).length,
            indices = [],
            rand;

        // Get all "-" char indexes
        for(var i=0; i < formula.length; i++) {
            if (formula[i] === "-") indices.push(i);
        }

        do {
            rand = Array(len).join().split(',').map(function() {
                return chrs.charAt(Math.floor(Math.random() * chrs.length));
            }).join('');

            // Rebuild string!
            if (indices && indices.length > 0)
            {
                for(var x=0; x < indices.length; x++)
                    rand = rand.insert(indices[x], '-');
            }
        } while (checks && $.inArray(rand, checks) !== -1);

        return rand;
    }
});

Ok, so, what I need to be able to do is to find total possible values and make sure that it is possible to generate a unique serial number before actually doing so.

For example:

var num = $.generateSerial('XX', 'AB', new Array('AB', 'BA', 'AA', 'BB'));

This will cause the code to do an infinite loop, since there are no more possibilties here, other than the ones being excluded from the extension. So this will cause browser to crash. What I need to be able to do here is to be able to get the number of possible unique values here and if it is greater than 0, continue, otherwise, don't continue, maybe an alert for an error would be fine.

Also, keep in mind, could also do this in a loop so as to not repeat serials already generated:

var currSerials = [];
for (var x = 0; x < 5; x++)
{
     var output = $.generateSerial('XXX-XXX-XXX', '0123456789', currSerials);
     currSerials.push(output);
}

But the important thing here, is how to get total possible unique values from within the generateSerial function itself? We have the length, characters, and exclusions array also in here (checks). This would seem more like a math question, and I'm not expert in Math. Could use some help here.

Thanks guys :)

Here is a jsFiddle of it working nicely because there are more possible choices than 16: http://jsfiddle.net/qpw66bwb/1/

And here is a jsFiddle of the problem I am facing: Just click the "Generate Serials" button to see the problem (it continuously loops, never finishes), it wants to create 16 serials, but 16 possible choices are not even possible with 2 characters and only using A and B characters: http://jsfiddle.net/qpw66bwb/2/

I need to catch the loop here and exit out of it, if it is not able to generate a random number somehow. But how?

Solomon Closson
  • 6,111
  • 14
  • 73
  • 115
  • FYI: `Array(len).join().split(',').map` can be just `Array(len).map` – Barmar Nov 18 '15 at 23:39
  • @Barmar - Actually `Array(len).join().split(',')` is needed here. Otherwise freezes script. – Solomon Closson Nov 19 '15 at 00:05
  • What is `.insert()` at `rand = rand.insert(indices[x], '-');` ? _"so as to not duplicate values"_ , _"But the important thing here, is how to get total possible unique values from within the generateSerial function itself?"_ , see http://stackoverflow.com/questions/9960908/permutations-in-javascript – guest271314 Nov 19 '15 at 00:30
  • So, if you notice, all `-` (if they exist in string) are removed and the indexes of these are stored in the `indices` array. So I can do something like this: `$.generateSerial('X-X-X', 'AB', new Array('B-B-B', 'A-B-A', 'A-B-B', 'A-A-A', 'B-B-A'));` or like this: `$.generateSerial('XXX-XXX-XX-XX-XX-XXX-XXX-XXXX');` and the indices get put back into the string where the indexes where in the `XXX` formula string. `.insert` puts back the `-` characters into the string to form the proper serial number according to the formula. – Solomon Closson Nov 19 '15 at 02:37
  • @guest271314 - that answer does not help me, cause I would also need to get repetitive values as well. But basically, what I need to know is if there is atleast 1 possible value for the `generateSerial` function to return, once it factors in the `checks` array of already assigned values. And let's not forget about repetitive characters as well, that is also considered a possible return value for `generateSerial` – Solomon Closson Nov 19 '15 at 02:43
  • @SolomonClosson Not certain interpret expected parameters , results correctly. Tried to call `generateSerial('X-X-X', 'AB', new Array('B-B-B', 'A-B-A', 'A-B-B', 'A-A-A', 'B-B-A'))` at `console` , returned `TypeError: undefined is not a function` . Can create stacksnippets to demonstrate ? – guest271314 Nov 19 '15 at 03:40
  • @guest271314 - You don't call the function like that, it is an extension onto jQuery. Here is how to use it: http://jsfiddle.net/qpw66bwb/ – Solomon Closson Nov 19 '15 at 03:53
  • And here is a better example of the use of `$.generateSerial`: http://jsfiddle.net/qpw66bwb/1/ – Solomon Closson Nov 19 '15 at 04:33
  • @SolomonClosson _"You don't call the function like that, it is an extension onto jQuery."_ Can be called as a function without extending jQuery http://jsfiddle.net/qpw66bwb/3/ . _"here is a better example of the use of $.generateSerial"_ Is expected result permutations of `n` items in a group of size `len`, repetitions allowed , with option to exclude specific groups from returned set ? – guest271314 Nov 19 '15 at 06:04
  • Should be able to determine possible number of permutations or combinations from input string or array length . If only two input items provided , only two possible combinations possible – guest271314 Nov 19 '15 at 06:10
  • Ok, but I don't know how to factor all of that in, asking for help here. I suppose I will just try and figure this out myself, not getting much help here I guess. – Solomon Closson Nov 19 '15 at 14:16
  • @SolomonClosson See http://stackoverflow.com/questions/7743007/most-efficient-way-to-write-combination-and-permutation-calculator-in-javascript , https://en.wikipedia.org/wiki/Permutation_group , https://en.wikipedia.org/wiki/Combination , http://home.ubalt.edu/ntsbarsh/Business-stat/otherapplets/comcount.htm – guest271314 Nov 19 '15 at 19:14

1 Answers1

1

The number of possible serials is len * chrs.length, assuming all the characters in chrs are different. The serial contains len characters to fill in randomly, and chrs.length is the number of possible characters in each position of that.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Ok, I'm lost here. I understand `len * chrs.length`, but how to get the rest? Would just add them together? – Solomon Closson Nov 18 '15 at 23:46
  • I thought you wanted to know the number of possible values, not generate a list of all of them. – Barmar Nov 18 '15 at 23:47
  • I guess I just need to know if it is possible for the loop to generate a random number or not based on the possibilities. Hope that makes sense. – Solomon Closson Nov 18 '15 at 23:48
  • Can't you just compare `check.length` to `len * chrs.length`? – Barmar Nov 18 '15 at 23:51
  • But not all characters in the string will be different also... So, will need to account for that as well. – Solomon Closson Nov 18 '15 at 23:52
  • Thanks, this answered my question actually. So, to check if any possibilities I use this: `var lenChecks = checks.length || 0; var possible = (len * chrs.length) - lenChecks;`, than if `possible <= 0 return '';` Thanks :) – Solomon Closson Nov 19 '15 at 15:42
  • If there can be duplicates, then instead of `chrs.length`, you'll need to count the number of different characters. jQuery and underscore.js both provide functions to remove duplicates from an array, and you can split the string into an array to use them. – Barmar Nov 19 '15 at 16:27