3

I require an algorithm to generate a set of stock item serial numbers, working from a starting serial.

For example, with a starting serial of B10S001, and generating 3 numbers, the result should be -

B10S001
B10S002
B10S003

However, with a starting serial of B10S998, and generating 3 numbers, the result should be -

B10S998
B10S999
B10T000

i.e. the number of numerics must remain the same, with the last alpha incrementing if necessary.

Note - I do not know the structure of the first serial number. It could be any length and any combination of alphas and numerics.

The code I'm using at the moment is :

public static string IncrementNumber(string pNumber) {
    string newNum = "";
    var match = Regex.Match(pNumber, @"(?<=(\D|^))\d+(?=\D*$)");
    if (match.Success) {
        var number = int.Parse(match.Value) + 1;
        newNum = string.Format(
            "{0}{1}{2}",
            pNumber.Substring(0, match.Index),
            number,
            pNumber.Substring(match.Index + match.Length));
        }
    return newNum;
}

This gets me some of the way, but removes the leading zeros, and doesn't increment the alpha. Don't know much about regex (copied above code from a forum post) - any ideas how to achieve this?

  • possible duplicate of [Add leading zeroes to number in Java?](http://stackoverflow.com/questions/275711/add-leading-zeroes-to-number-in-java) – Barmar Jan 10 '13 at 08:20
  • which language? is it ok if it is perl? – Vijay Jan 10 '13 at 08:25
  • sarathi - using C# on .net 3.5. How difficult would it be to incorporate perl ? (happy to use so long as it doesnt cause any deployment issues etc) – Andrew Austin Jan 10 '13 at 08:51
  • sorry - should mention, the examples listed may not necessarily be the serial number structure used. In essence, I would need to accomodate any lenght of alphas and numerics provided by the starting serial number, and then look at the right-most numerics and alpha to apply the logic ? – Andrew Austin Jan 10 '13 at 09:07
  • was tagged java ; plus is it normal that after `B10S999` is `B10T001` and not `B10T000`?? – UmNyobe Jan 10 '13 at 09:34
  • umnyobe - yes quite right, the overflow should infact be B10T000, not B10T001 - thanks for pointing it out – Andrew Austin Jan 10 '13 at 09:46

3 Answers3

1

Given that you have the integer value and the letter, here is some pseudocode for what you need to do:

fun CreateSerial(value, letter):
  value = value + 1
  if value == 1000:
    letter = letter + 1
    if letter > 'Z':
      letter = 'A'
  if value < 10:
    return "B10" + letter + "00" + value
  else if value < 100:
    return "B10" + letter + "0" + value
  else:
    return "B10" + letter + value

EDIT: Here is pseudocode for doing it without pattern matching.

fun IncrementSerial(serial):
  IncrementNext(serial, serial.length - 1)

fun IncrementNext(serial, index):
  if index == 0:
    return
  if serial[index - 1] is numeral:
    IncrementNumeral(serial, index - 1)
  else:
    IncrementAlpha(serial, index - 1)

fun IncrementNumeral(serial, index):
  number = serial[index] + 1
  if number > '9':
    number = '0'
    IncrementNext(serial, index - 1)
  serial[index] = number

fun IncrementAlpha(serial, index):
  alpha = serial[index] + 1
  if alpha > 'Z':
    alpha = 'A'
    IncrementNext(serial, index - 1)
  serial[index] = alpha

Essentially we increment letters starting from the end, and if we overflow, then we reset the letter and go to the next, checking what type it is at each iteration (numeral vs alpha).

If we get to the max serial number, it just returns, optionally you could have it reset everything.

Alex DiCarlo
  • 4,851
  • 18
  • 34
1

You'll need to implement addition 'by hand', just like you do long addition on a piece of paper. First, you need to treat your string as a number, where every digit is in a different basis. The 3rd right-most digits are in the base of 10, the rightmost letter is in base-26, then two base-10 digits, then, probably, another base-26 digit.

Now that you have this, start incrementing digits one-by-one, from the right. Take the rightmost digit and increment it by 1. If there's no overflow (that is, you didn't get from 9 to 0), you're done. If there is an overflow, the digit turns back to 0, and you need to increment the digit to its left.

When you get to B10S999 you increment the rightmost digit and get an overflow. Then you increment the second-to-right digit and get an overflow. Then the next digit and get an overflow. Now you have increment the S. The next letter is T, so you get B10T000.

After you get to B10Z999 and increment, you'll get four overflows, and end up with B11A000.

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • thanks - was hoping for some built in functions in .net / regex rather than a 'by hand' option, but looks like that will be the way to go. Dicarlo2 pseudocode below looks like the same logic - am going to try implement something like this and see if I get the result. – Andrew Austin Jan 10 '13 at 09:39
0

Why don't you put all your logic in one class and be done with it? Apparently you have 4 parts on your serial,

 class Serial{
     Serial(string s);

     char prefixLetter;
     int prefixNum;
     char middleLetter;
     int traillingNum;

     void increment();
     bool isvalid();
     string toString();

     //etc....
 }
UmNyobe
  • 22,539
  • 9
  • 61
  • 90