5

Trying to code a general 4 digit alphanumeric series in PHP.

Pattern is as follows
0000
0001
....
....
9999
A000
A001
....
....
A999
B000
....
....
Z999
AA00
....
....
AA99
AB00
....
....
ZZ99
AAA0
....
....
AAA9
AAB0
....
....
ZZZZ

I was trying to make the logic based on the no of Z and no of 9, but could not get anything concrete going.

I am trying to write a code that will return me the next number of the series on inputting the last number of the series.

Any hints or leads will be appreciated

Shivanshu Gupta
  • 248
  • 1
  • 14
  • You need to generate range of values or just you need to return a single value next to the value you input? – Thamilhan Jun 13 '16 at 05:13
  • I just need to return the next value that I input. – Shivanshu Gupta Jun 13 '16 at 05:20
  • I arrived at a solution, but a question: How come `9999` become `A000` but `Z999` becomes `AA00`? Can you give me the series so it can be set there. Am so far using `'0','1','2','3','4','5','6','7','8','9','A','B',.....'Y','Z'` – Thamilhan Jun 13 '16 at 06:04
  • 1
    Yes, correct This is the series that is to be used First we exhaust all the number set, After 9999 -> A000 Then exhaust all the number set with A i.e till A999->B000....till Z999 Now we have exhausted all the number range with single alphabet. So now next element will be AA00 and then the same pattern follows – Shivanshu Gupta Jun 13 '16 at 06:10

2 Answers2

1

This is actually quite easy when using PHP's built-in increment operator which is capable of handling alphanumeric sequences like this.

There are two boundary exceptions that need to be manually handled:

  1. making the first jump from numeric to alphanumeric
  2. terminating the series

<?php

function getNext($input){

  // boundary cases
  switch($input){

    // bridge numeric to alphanumeric
    case '9999': return 'A000';

    // terminate sequence, instead of expanding to 5 digits 'AAAA0'
    case 'ZZZ9': return 'ZZZA';

    // start over
    case 'ZZZZ': return '0000';

  }

  // normal increment
  $input = substr(++$input,0,4);

  // pad with leading zeros
  return str_pad($input, 4, '0', STR_PAD_LEFT);

}

$samples = [
  '0000','9999','A000','A999','Z999','AA99',
  'ZZ99','AAA9','ZZZ9','ZZZA','ZZZY','ZZZZ'
];

foreach ($samples as $sample)
  echo $sample . ' -> ' . getNext($sample) . PHP_EOL;

0000 -> 0001
9999 -> A000
A000 -> A001
A999 -> B000
Z999 -> AA00
AA99 -> AB00
ZZ99 -> AAA0
AAA9 -> AAB0
ZZZ9 -> ZZZA
ZZZA -> ZZZB
ZZZY -> ZZZZ
ZZZZ -> 0000

See this related answer.

Community
  • 1
  • 1
Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
0

You could try something like this:

<?php

function generateNext($input) {
    $numbers = (int) preg_replace('/[^0-9]/', '', $input);
    $letters = preg_replace('/[^a-zA-Z]/', '', $input);

    if($numbers >= 99) 
    {
        $letters = ++$letters;
        $numNumbers = 4 - strlen($letters);
        if($numNumbers === 0) 
        {
            $numbers = "";
        }
        else
        {
            $numbers = str_pad("1", $numNumbers, "0", STR_PAD_LEFT);
        }

        $final = $letters.$numbers;
    }
    else if($input == "ZZZ9")
    {
        $final = "ZZZZ";
    }
    else 
    {
        $numbers = ++$numbers;
        $numNumbers = 4 - strlen($letters);
        if($numNumbers === 0) 
        {
            $numbers = "";
            $letters = ++$letters;
        }
        else
        {
            $numbers = str_pad($numbers, $numNumbers, "0", STR_PAD_LEFT);
        }

        $final = $letters.$numbers;
    }

    return $final;

}

?>
Praneeth
  • 83
  • 1
  • 8
  • Hi, First of all I think in the first if block, the str_pad line needs to be replaced with $numbers = str_pad("0", $numNumbers, "0", STR_PAD_LEFT); because next number after Z999 should be AA00 and not AA01. Coming to the rest of the code, you have covered all the edge cases I guess, but you have missed out on the general series. Your code increments the letters no matter what if the numbers are 99 or greater, so this code will return AA00 on inputting Z234 whereas it should give Z235 – Shivanshu Gupta Jun 13 '16 at 06:34