I’ve been doing the Perl Weekly
Challenges. The
latest
involved finding the trailing zeroes of a factorial and printing a
range of lines from a file.
You are given a positive integer $N
(<= 10).
Write a script to print number of trailing zeroes in $N!
.
There's an easy way and a hard way to do this. Let's do the
(computationally) hard way first: actually calculate the factorial (in
a library where precision will be retained), and count the zeroes at
the end.
use Math::GMP;
sub zerofact {
my $n=shift;
$n=Math::GMP->new($n);
my $f=$n->bfac->get_str_gmp(10);
my $l=0;
$f =~ /(0+)$/;
if (defined $1) {
$l=length($1);
}
return $l;
}
The easier way, which I used in Raku, is not to calculate the
factorial at all, but rather to consider that a trailing zero is the
result of a pair of (2,5) among the prime factors. And there will
always be at least as many twos as fives, so we just need to count the
fives. So 0..4 has a result of 0, 5..9 a result of 1, 10..14 2, etc. A
slight complication is that at n=25 we add two factors of five, at
n=125 three, etc.
sub zerofact($n) {
my $k=5;
my $t;
my $a=0;
repeat {
$a=floor($n/$k);
$t+=$a;
$k*=5;
} while ($a>0);
return $t;
}
(It's still slower than Perl though.)
You are given a text file name $file
and range $A
- $B
where
$A <= $B
.
Write a script to display lines range $A
and $B
in the given
file.
Well, that's very straightforward. The only slight cleverness is that
we can jump to the end when we hit line number $B
.
sub range {
my $fn=shift;
my $a=shift;
my $b=shift;
my $n=0;
open I,'<',$fn;
while (<I>) {
$n++;
if ($n > $b) {
last;
}
if ($n>=$a) {
print $_;
}
}
close I;
}
and Raku is basically identical.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.