# Perl Weekly Challenge #72

### TASK #1 › Trailing Zeroes

Submitted by: Mohammad S Anwar

You are given a positive integer $N (<= 10).

Write a script to print number of trailing zeroes in $N!.

There are two basic issues here:

- Factorial
- Character counting

For those without the math background, **factorial** means *multiply every digit from 1 to n together*. For *5!*, for example, it’s *1 * 2 * 3 * 4 * 5 = 120*. This can be done many ways. I chose *reduce*.

Reduce is commonly paired with *map*, which allows you to modify and expand an array, but reduce allows you to get one value for the array. We can say *sum* with `reduce { $a + $b }`

. *min* would be `reduce { $a < $b ? $a : $b }`

, and thus *max* would be `reduce { $a > $b ? $a : $b }`

.

But, what we need here is *factorial*.

`reduce { $a * $b } 1 .. $n`

.

Next is counting the number of trailing zeroes.

This looks like a job for **Regular Expressions!**

So, match a trailing zero. `$f =~ /0$/`

Match one or more trailing zeroes. `$f =~ /0+$/`

Let’s store that. `my ($z) = $f =~ /(0+)$/`

So, n = `7`

, f = n! = `5040`

, and z would be `0`

. `length $z`

would be `1`

. There we have it.

```
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw{ say signatures state };
no warnings qw{ experimental };
use Carp;
use Getopt::Long;
use List::Util qw{ reduce };
my $n = 4;
GetOptions( 'n=i' => \$n, );
croak 'n must be positive' if $n < 1;
croak 'n must be less than 11' if $n > 10;
my $f = factorial($n);
my $t = trailing($f);
my $zero = 'zero';
$zero = 'zeroes' if $t > 1;
say qq{Output: $n as N! = $f has $t trailing $zero};
sub trailing( $f ) {
my ($z) = $f =~ /(0+)$/mix;
return length $z || 0;
}
sub factorial ( $n ) {
return reduce { $a * $b } 1 .. $n;
}
```

### TASK #2 › Lines Range

Submitted by: Mohammad S Anwar

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.

I don’t think I’ve shown File IO in a while, if ever.

If we added `use English`

, we could use the name of the current program as `$PROGRAM_NAME`

, but since I’m not doing anything else with that, I’ll just use `my $f = $0`

.

I use Carp and `croak`

to handle bad input, including the file test `-f`

to ensure that the file we have exists, as well as ensure that the range min and max make sense.

And now, we open the file so we can check the lines. I normally do a file check when I open the file — `if ( -f $file && open my $fh, '<', $file ) { ... }`

— but the file check occurs earlier, so that isn’t necessary. Then there’s simply numbering each line and printing the line when the number is right. Easy peasy.

```
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw{ say signatures state };
no warnings qw{ experimental };
use Carp;
use Getopt::Long;
my $f = $0; # this program
my $a = 1;
my $b = 4;
GetOptions(
'f=s' => \$f,
'a=i' => \$a,
'b=i' => \$b,
);
show_lines( $a, $b, $f );
sub show_lines ( $a, $b, $f ) {
my $c = 0;
if ( open my $fh, '<', $f ) {
my @array = <$fh>;
for my $i (@array) {
$c++;
next if $c > $b;
next if $c < $a;
print $i ;
}
}
}
```