[Perl] my quiz (easy)
Mikhael Goikhman
migo at homemail.com
Wed Oct 23 13:36:28 PDT 2002
On 23 Oct 2002 11:47:50 +0200, Shlomo Yona wrote:
>
> Write a sub which receives some integer number
> greater than zero (lets call the number N), and
> return a string of N characters (over [A-Za-z0-9]).
>
> Calling the sub within the same run of the program should
> guarantee no two strings of length N are equal (i.e. all the
> strings of same length are uniqe).
Here is the solution with the best performance (both memory and speed).
It circulates: "000" .. "999", "AAA" .. "ZZZ", "aaa" .. "zzz", "000".
It utilizes a feature of the ++ operator for "\d+" and "\w+" strings.
#!/usr/bin/perl -w
use strict;
my %uniques = ();
sub unique {
my $len = shift;
# let's limit our unique string length from 1 to 99 chars
return undef unless defined $len && $len =~ /^[1-9]\d?$/;
# initialize to "000" if this is the first time with $len
$uniques{$len} ||= "0" x $len;
# advance to the next unique string in one of the 3 ranges
return $uniques{$len}++ if length($uniques{$len}) == $len;
# otherwise switch the range: digits -> upper -> lower -> digits
my $overflow = substr($uniques{$len}, 0, 1);
$uniques{$len} = "A" x $len if $overflow eq "1";
$uniques{$len} = "a" x $len if $overflow eq "A";
$uniques{$len} = "0" x $len if $overflow eq "a";
return $uniques{$len}++;
}
# test this function
printf "Expected string: '%s', got string: '%s'\n", $_, unique(1)
foreach ("0" .. "9", "A" .. "Z", "a" .. "z", "0" .. "9", "A");
printf "Expected string: '%s', got string: '%s'\n", $_, unique(2)
foreach ("00" .. "99", "AA" .. "ZZ", "aa" .. "zz", "00");
> Let's see who writes the nicest and perhaps smartest peace of code.
I am glad you don't ask for the "shortest". Although nice solutions are
usually short, the number of the chars used has nothing to do with this.
Regards,
Mikhael.
More information about the Perl
mailing list