Re: [SPOILER] Perl 'Easy' Quiz #2005-2

Daniel Martin <martin-+m399P62/[email protected]> Sat, 05 Feb 2005 12:58:51 -0500
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Bill Smith <[email protected]> writes:

> I am not convinced that "maskit"
> will work for all input strings,
> but I have not found an example 
> where it does not work correctly.

Here's the string: "$mask$mask".  maskit on that routine returns
$mask.

Here's the simplest fix I could come up with:

sub maskit{
 my $mask = '#@%';
 ($_ = $_[0]) =~ s/\.([^.]*)$/$mask$1/;
 return $_ unless defined($1);
 tr /\.//d;
 { no warnings; s/$mask($1)$/.$1/; }
 return $_;
}

Of course, then there's no need for that complicated value for $mask;
you might as well use '_':

sub maskit2{
 ($_ = $_[0]) =~ s/\.([^.]*)$/_$1/;
 return $_ unless defined($1);
 tr /\.//d;
 { no warnings; s/_($1)$/.$1/; }
 return $_;
}

Or you could even use the empty string:

sub maskit3{
 ($_ = $_[0]) =~ s/\.([^.]*)$/$1/;
 return $_ unless defined($1);
 tr /\.//d;
 { no warnings; s/($1)$/.$1/; }
 return $_;
}

But at this point, you don't need that initial substitution, so:

sub maskit4{
 ($_ = $_[0]) =~ /\.([^.]*)$/;
 return $_ unless defined($1);
 tr /\.//d;
 { no warnings; s/($1)$/.$1/; }
 return $_;
}

-----------

But now something else - your last two routines were blindingly fast
compared to every other routine posted here - compare these timings to
what I posted before:

             Rate
maskit     8.07/s
reverseit  71.3/s
oneatatime  255/s
recurse     295/s

A closer check made me realize that this is because these routines
clobber $_, which means that in my test routine they're constantly
running over strings that have only one period.  Adjusting my
cmpit perl script gave the real times:

maskit     7.49/s
recurse    11.0/s
oneatatime 14.7/s
reverseit  99.8/s

I'm surprised at how fast reverseit is - I would expect it to fair no
better than something like my regexpTr routine.