SPUG: auto-increment mixed alpha-numeric

Chris Wilkes cwilkes-spug at ladro.com
Thu Mar 13 14:04:50 CST 2003


On Thu, Mar 13, 2003 at 11:28:08AM -0800, Richard Wood wrote:
> Here is what I am using in the meantime while waiting
> for an elegant solution.

You might have to keep on waiting after this post ;)

What I've done is created a new package variable called FunkyNumber that
does your adding up in base 36 (base 10 + 26 letters).  I've overloaded
the ++ so that you can add to it.  Substraction is just adding an
overloader.

Run it and you'll see a case like this:
  2ZY     2ZZ     300     301 
which I think is what you want.

I've probably made some grievous perl error in my code, I've been known
to do that.

Chris

#!/usr/bin/perl

package FunkyNumber;
use strict;

use overload
   '+' => \&myadd,
   '++' => \&myadd,
   '""' => \&myprint;


sub new {
   my ($proto, $class, $val, $self);
   $proto = shift;
   $class = ref($proto) || $proto;
   $val = shift || "AAA";
   $self = {};
   $self->{val} = $val;
   bless ( $self, $class);
   return $self;
}

sub myadd {
   my $self = shift;
   my ($carry, @stack, $pos);
   @stack = reverse split //, $self->{val};
   while (1) {
      $stack[$pos]++;
      # check to see if we've gone from z -> aa or 9 -> 10
      last unless (length($stack[$pos]) == 2);
      my $change = substr($stack[$pos], 0, 1);
      if (substr($stack[$pos], 0, 1) eq "A") {
         $stack[$pos] = 0;
      } else {
         $stack[$pos] = 'A';
      }
      $pos++;
      last if ($pos > $#stack);
   }
   $self->{val} = join "", reverse @stack;
}

sub myprint {
   my $self = shift;
   return $self->{val};
}

package main;
use strict;

my @strings = qw(AAA AA8 A8A A98 118 18A 2ZY 8AA A1Z);

foreach my $str (@strings) {
   my $s = FunkyNumber->new($str);
   foreach (0..3) {
      print "$s\t";
      $s++;
   }
   print "\n";
}



More information about the spug-list mailing list