🎄 23/25. Calculating totals with Perl 6

🎄 23/25. Calculating totals with Raku

N. B. Perl 6 has been renamed to Raku. Click to read more.

Welcome to Day 23 of the Perl 6 One-Liner Advent Calendar! End of the year is the time when people evaluate there year results, and Perl 6 can help with that, too.

Today, we’ll see a one-liner that calculates totals for the columns of a table.

Here’s some sample data in a file:

100.20  303.50 150.25
130.44 1505.12 36.41
200.12 305.60 78.12

And here’s the code that prints three numbers—totals for each column:

put [Z+] lines.map: *.words

The program prints the numbers that we need:

430.76 2114.22 264.78

From the update of yesterday’s post, we know that bare lines is the same as $*IN.lines, so lines.map iterates over all the lines in the input stream. Each line is then split into words—substrings separated by whitespaces.

The part of the job that parses input data is complete. We have got a number of sequences corresponding to the lines of input data. For our sample file, these are the following:

(("100.20", "303.50", "150.25").Seq, ("130.44", "1505.12", "36.41").Seq, ("200.12", "305.60", "78.12").Seq).Seq

Now, add up every first element, every second element, etc. The combination of the reduction operator and the zip meta-operators does all the work with only four characters of code: [Z+].

At this point, we have a reduced sequence:

(430.76, 2114.22, 264.78).Seq

The last trivial step is to print the values using the put routine. If you did the homework yesterday, you would know that say uses the gist method (which adds parentheses around a sequence) to visualise the result, while put simply prints the values using the Str method.

An addition

Let us add a few more characters to the script to demonstrate how you can skip the first column that, for example, contains month names:

Jan 100.20  303.50 150.25
Feb 130.44 1505.12 36.41
Mar 200.12 305.60 78.12

All you need is to make a slice and select all columns except the first one:

put 'Total ', [Z+] lines.map: *.words[1..*]

As you see, we even don’t need to count columns ourselves. The 1..* range can make that job.

And that’s the end of today’s advent post, so come again tomorrow!

3 thoughts on “🎄 23/25. Calculating totals with Perl 6”

  1. A much more efficient way to skip the first element of a `Seq` is to use the `skip` method: `dd .skip.sum # 50`. And perhaps even better to read as well in this case. Of course, this only helps if you need to skip the first N entries of a `Seq`

Leave a Reply

Your email address will not be published. Required fields are marked *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code