patternModerate
Perl 6 oneliner to sum up all numbers in a text file
Viewed 0 times
fileallperlnumberstextsumoneliner
Problem
The task is to sum up scores mentioned in a text file. Scores are floating point numbers as defined by the regexp
Example input
The expected sum here is 5 + 2.8 - 1 = 6.8.
The code works, but it prints out a large number of warning messages
I would like to hear suggestions how to write this in a more idiomatic Perl.
In addition, I would like to hear how to make it more an one liner since I guess the code might be written with significantly less lines and still be readable.
float immediately preceded by a * character to distinguish them from other numbers in the text. Scientific notation is not permitted.Example input
Day 1:
Task 1: *5 Task 2: *2,8
Task 3 was the hardest, your score is *-1
…The expected sum here is 5 + 2.8 - 1 = 6.8.
my $sum = 0;
my regex float {
(?) # opt. sign
(\d+) # whole part
[()(\d*)]? # opt. fractional part;
# comma is a valid separator
}
for slurp.match( / \* /, :g ) {
my $f = $_;
# justification for the next line:
# +"5," Cannot convert string to number: trailing characters after number
# +"5." Cannot convert string to number: radix point must be followed by one or more valid digits
$sum += +"$f[1]$f[2].$f[4]0"
}
say $sum;The code works, but it prints out a large number of warning messages
use of uninitialized value of type Any in string contextI would like to hear suggestions how to write this in a more idiomatic Perl.
In addition, I would like to hear how to make it more an one liner since I guess the code might be written with significantly less lines and still be readable.
Solution
The warning comes from the fact that the third and fourth capture groups are inside an optional part of the regex. Therefore,
Rather than concatenating the parts of a decomposed number, I suggest taking all of
$f[4] might not be defined.Rather than concatenating the parts of a decomposed number, I suggest taking all of
$f[0] and replacing any comma with a period.my $sum = 0;
my regex float {
? # opt. sign
\d+ # whole part
[ \d+ ]? # opt. fractional part
#comma is vaild separator
}
for slurp.match( / \* /, :g ) {
$sum += +$_.subst( /','/ , '.' , :g );
}
say $sum;Code Snippets
my $sum = 0;
my regex float {
<[+-]>? # opt. sign
\d+ # whole part
[ <[.,]> \d+ ]? # opt. fractional part
#comma is vaild separator
}
for slurp.match( / \* <float> /, :g ) {
$sum += +$_<float>.subst( /','/ , '.' , :g );
}
say $sum;Context
StackExchange Code Review Q#72123, answer score: 10
Revisions (0)
No revisions yet.