[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