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