Reputation: 651
So, I wrote a script which calculates the factorials of 4^(0) to 4^(10) as I wanted to test the run-times, and I also wanted to compare Stirling's approximation with the with the actual number of digits of the respective factorials.
So I have a file with this data called factorials.txt which contains the following data for example:
The factorial of 1 is
1
The factorial of 4 is
24
The factorial of 16 is
20922789888000
The factorial of 64 is
126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000
I would like the output of the factorials to be the following:
Factorial 1: 1 digits.
Factorial 4: 2 digits.
Factorial 16: 14 digits.
Factorial 64: 90 digits
I was able to write a script to get these values, where after my statement for the factorial of ___ is ... on the next line is the value of the factorial. But I wasn't able to select the next line after the match, so I wrote this much using a while loop through the file matching for the nonexistence of letters, and then printing the length of the characters on the line. It works, but I don't think that it's very efficient.
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
my $file = 'factorials.txt';
my $filehandle;
open($filehandle, '<', $file) or die "Could not open file $_ because $!";
while(my $line = <$filehandle>)
{
chomp $line;
my $index = $.;
if($line !~ m/[a-z]/)
{
say length($line);
}
}
My script outputs the following, for example:
1
2
14
90
I want the parsing script to if it matches the word "factorial" on the line, print the length of characters on the next line. I believe this must be possible, but I can't seem to figure out how to go to the next line.
Any ideas? Thanks so much!
Upvotes: 0
Views: 600
Reputation: 54333
The whole thing can be much simpler than that. All you need is one specific match.
The following code will check for the text with the number that you've built the factorial of. If it finds that, it print
s the label. It does that by capturing the number into $1
. The print
does not have a line break.
If it doesn't find it, it assumes the whole line is the one with the factorial, so it say
s the length
of the line. This will now have the line break, and the next output will go to the next line.
The chomp
is important for the length
to work correctly.
use strict;
use warnings;
use feature 'say';
while (my $line = <DATA>) {
chomp $line;
if ( $line =~ m/factorial of ([0-9]+)/) {
print "Factorial of $1: ";
} else {
say length $line;
}
}
__DATA__
The factorial of 1 is
1
The factorial of 4 is
24
The factorial of 16 is
20922789888000
The factorial of 64 is
126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000
And the output:
Factorial of 1: 1
Factorial of 4: 2
Factorial of 16: 14
Factorial of 64: 90
Upvotes: 3