Welcome to the monthly series `Meet The Champion`

.

Last month we spoke to **Myoungjin Jeon**, the winner of **September 2020**.

Today we are talking to **Andrew Shitov**, the winner of **October 2020** of `The Weekly Challenge`

. I hope you are going to enjoy the interview.

**Mohammad:** Tell us about your technical background?

**Andrew:** Well, being a **PhD** in **Physics** and **Mathematics**, I used **C++** a lot for computing things happening in nuclear collisions, which in the end turned me to work in the world of programming rather than science. Since then, I was mostly working with the main people driving the Internet and Web in Russia. **Perl** was the main tool, but I was always having fun with other languages and platform, including programming for microcontrollers when it was not the mainstream yet.

**Mohammad:** How/When did you start using **Perl**/**Raku**?

**Andrew:** I started using **Perl** somewhen about just before **2000**. A friend of mine said there’s a language where you can write `if`

either before or after the thing. I believe that was the trigger for me.

By the way, the date is surprisingly close to when **Perl 6** was announced, and I followed it since pretty much the beginning. Therefore the frustration mood when it did not go well or when the **Perls** were battling for the version number, or when it was proposed to be renamed, or when it was finally renamed to the same earlier rejected name, etc. I wonder what to expect in the future

**Mohammad:** How did you come to know about `The Weekly Challenge`

?

**Andrew:** It was not a problem to hear about the initiative if you follow the main news sources about **Perl** and (now) **Raku**. But I can’t say I was enthusiastic about the project. Neither I could predict it lasts for such a long time already. I am looking forward to the 100^{th} issue.

**Mohammad:** What do you like the most about `The Weekly Challenge`

?

**Andrew:** There is no doubt that the main achievement is the number of blog posts that the participants wrote alongside their solutions. The historians should do a research on how that helped **Perl** and **Raku**, but it is also obvious that it did not help much to overcome the borders of the echo chamber.

The second thing — rather on a personal development level — I think it really helps people to attend their programming gym regularly and for free. Most of the tasks are compact enough to be solved in a few minutes. While not taking much time, they are helping in refreshing different programming tricks and techniques, which is a huge help for everyone (of all ages).

**Mohammad:** How much time you dedicate every week to `The Weekly Challenge`

?

**Andrew:** I started solving the tasks since around Week 65, and then retrospectively solved many assignments from earlier weeks. My original idea was to spend half an hour per task at maximum including writing a blog post about the solution.

Then I decided to make weekly reviews of the Raku solutions, which broke the initial plan, so it now takes a bit more than half an hour, which makes it more difficult to follow the schedule diligently.

**Mohammad:** Do you checkout others solutions and who is your favourite?

**Andrew:** Well, the answer is obvious if you’ve just read the previous answer. But seriously, I mostly never look at the other solutions before I finish (and commit) mine. In most cases, I am interested in **Raku** solutions only, but I also lurk into Perl solutions occasionally.

Speaking of **Raku** solutions, I honestly enjoy most of them. There are solutions which I find written in a foreign style for me, but on the other hand, they often demonstrate such great pearls of Raku that you only have your jaw dropped. I am sure that **Raku** still keeps dozens of tricks that nobody discovered so far. That’s one of the fascinating things about the design of this language.

**Mohammad:** What do you suggest someone just started `The Weekly Challenge`

?

**Andrew:** Grab a task that you find simple enough. If there’s none this week, scan the previous weeks and pick one from there. Also keep in mind that the output of the problems is often not strictly defined in the task, so you may freely interpret the details and make your own choice for a simpler program. Yes, I believe that the simplicity and clarity of solutions is the main goal that the participants must seek.

**Mohammad:** Anything else you would to like to share with us?

**Andrew:** Complete the rename of the project to ‘The Weekly Challenge’ already and extend the language coverage

That brings the end of the conversation with **Andrew Shitov**. Please do let us know your view. We will come back next month with another champion.

The solutions of this week actually make me think that Raku changes my definition of what is a *straightforward solution*. All those tiny Raku bits such as `any`

or `X`

or `^$N`

are awesome even in a not fully-optimised program.

You are given an array of real numbers greater than zero. Write a script to find if there exists a triplet `(a, b, c)`

such that `1 < a + b + c < 2`

. Print 1 if you succeed otherwise 0.

So, the task is to find such three numbers from the given list so that they add up to a number between 1 and 2. Sounds as a good task for using the `combinations`

routine.

my @r = 1.2, 0.4, 0.1, 2.5; say +so 1 < any(@r.combinations(3)>>.sum) < 2;

As you see, the solution is extremely short. It creates the possible 3-element combinations from the input data and computes the sums of each. Then, we make a test `1 < any(...) < 2`

using the `any`

-junction, which allows us to avoid any explicit loops in the program. Finally, the `+so`

construct converts the result to first to a Boolean value (`so`

), and then to either 1 or 0 as the task requires.

You are given a positive integer `$N`

. Write a script to find if it can be expressed as `a ^ b`

where `a > 0`

and `b > 1`

. Print 1 if you succeed otherwise 0.

Well, some mathematics can be applied before going to the code, but let’s skip this useful step

my $N = @*ARGS[0] // 8; for 1..^$N X ^$N -> ($a, $b) { say "$N = $a^$b" if $N == $a ** $b; }

The program is quite wordy and self-explanatory, but I must mention that parentheses around loop variables are important here. Without them, you will get two pairs such as `(7 2) (7 3)`

on each iteration instead of just two integers.

The program prints all the possible solutions, and prints nothing if it could not find it.

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

Consider the following example:

sub f($a, *@b) { say "Head: $a"; say "Tail: @b[]"; } f(42, 43, 44);

The signature of the function has two elements: a scalar `$a`

and a slurpy array `@b`

. When you call `f`

with three parameters, the first one goes to `$a`

, and the rest land in `@b`

.

The program prints:

$ raku sub.raku Head: 42 Tail: 43 44

Let us apply the pattern from the example to a program that recursively computes the sum of the elements of an array of numbers:

multi sub rsum($head) { $head } multi sub rsum($head, *@rest) { $head + rsum(|@rest) } say rsum(10, 20, 30, 40, 50); # 150

There are no assignments here, so this program is a perfect example of programming in a functional style in Raku.

We have two versions of the `rsum`

functions here. One needs a single value, and the second one accepts additional (but required) array. While there are more than one element in the data list, the second version of the function is run. On the last iteration, a single elements remains, and thus the simpler version of the function is executed. The sum of a single element is the element itself. In the output, you get the desired sum.

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>Here is an interesting example of how you can use the any-junction in a single operation where you would traditionally should have a loop.

my $a = 40;

my @b = 1..5;

say 'Found the answer' if $a +any(@b)== 42;

Examine the addition `$a + any(@b)`

. We compare its result with a single number `42`

as if `any(@b)`

were a single integer.

`any`

A classical example of using any-junctions is something like this:

say 'There are negative ints' if 1|-2|3 < 0;

An alternative syntax — use a function:

say 'There are negative ints' ifany(1, -2, 3)< 0;

Another option — a method:

say 'There are negative ints' if (1, -2, 3).any< 0;

`all`

The following examples are similar to the examples from the previous section but employ the all-junction instead:

say 'Only positive ints' if 1&2&3 > 0; say 'Only positive ints' ifall(1, 2, 3)> 0; say 'Only positive ints' if (1, 2, 3).all> 0;

`MAIN`

Imagine a program that takes integer numbers from command line. You need to distinguish between the cases when the integers are either all positive or all negative.

One of the possible ways to check the input data is to use `multi MAIN`

functions and dispatch their calls using the `where`

clauses.

multi sub MAIN(*@a where @a.elems > 0 &&.all ~~ Int && .all > 0) { say 'All positive integers' } multi sub MAIN(*@a where @a.elems > 0 &&all(@a) < 0 && all(@a) ~~ Int) { say 'All negative integers' }

I am using two different forms of creating the all-junction: `.all`

and `all(@a)`

. You are free to build a WhateverCode block too.

There `where`

clauses demand that all of the input data (i.e., the elements in `@a`

) are integers (`.all ~~ Int`

) and either positive (`.all > 0`

) or negative (`all(@a) < 0`

).

Run the program with different input data:

$ raku all-1.raku 10 20 30All positiveintegers $ raku all-1.raku -10 -20 -30All negativeintegers $ raku all-1.raku -10 -20 30 Usage: all-1.raku [<a> ...] all-1.raku [<a> ...]

The previous example can be re-written in a different style that introduces new data types to the program:

subset PositiveInt of Int where * > 0; subset PositiveIntArray of Array where.all~~ PositiveInt && .elems > 0; subset NegativeInt of Int where * < 0; subset NegativeIntArray of Array where.all~~ NegativeInt && .elems > 0; multi sub MAIN(*@a where *~~ PositiveIntArray) { say 'All positive integers' } multi sub MAIN(*@a where *~~ NegativeIntArray) { say 'All negative integers' }

The subsets define the rules, and you can use them directly in the `where`

clauses in other functions.

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>`wrap`

routine and its possible applications.
`wrap`

The `wrap`

routine — as you may guess from its name — wraps another function. Let us go straight to the example.

sub greet($name) { say "Hello, $name!"; } &greet.wrap({ callwith($^arg.uc) }); greet('Venusians'); # Hello, VENUSIANS!

First, we’ve got a regular function that takes a string and prints the message with it. In the end, the function is called as usual.

In-between, we see that the function is wrapped into another function, which is actually called when you call `greet`

*instead of it*. In this example, the wrapping function calls the original function with the modified argument: `callwith($^arg.uc)`

. Here, `$^arg`

is a placeholder variable that the wrapper gets when the original function is called in the last line of the program.

`unwrap`

Let us extend the previous program and remove the wrapper after some time. To do that, you need to save the wrapper object in a variable, which you can later pass to the `unwrap`

routine.

sub greet($name) { say "Hello, $name!"; }my $x= &greet.wrap({ callwith($^arg.uc) }); greet('Venusians'); # Hello, VENUSIANS! &greet.unwrap($x); greet('Venusians'); # Hello, Venusians!

One of the useful examples of wrappers can be measuring time of execution of a slow function. Here is how you can do it:

sub slow { sleep(1); }sub timer { my $t0 = now; callsame; say now - $t0; }&slow.wrap(&timer); slow();

This time, the wrapper uses `callsame`

to call the original function with the same arguments. In this example, I am using a bit different syntax of calling the `wrap`

method. This option is more suitable for bigger wrapping functions.

Another example — a logger that you can place around a function that visits the sites, for example.

use HTTP::UserAgent; sub browse($url) { my $ua = HTTP::UserAgent.new; my $response = $ua.get($url); say $response.status-line; }&browse.wrap(-> $url {note "{DateTime.now} $url";callsame; });browse('https://google.com/'); browse('https://raku.org/');

Again, just for the sake of diversity, I used a pointy block here. You do not need to change the `browser`

function to start logging. Just create a wrapper which does the job:

$ raku wrap-log.raku > /dev/null 2020-09-17T23:04:32.383453+02:00 https://google.com/ 2020-09-17T23:04:32.807365+02:00 https://raku.org/

And that’s it for now!

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>`-rw`

suffix.
`substr-rw`

With a regular `substr`

routine (used as either a method or a function), you get a copy of the substring, which is an immutable value. If you want to modify the original string, you can use `substr-rw`

.

Consider the following two examples of using it:

my $string = 'Hello, World!'; $string.substr-rw(7, 5) = 'Mundo'; my $greeting := $string.substr-rw(0, 5); $greeting = '¡Hola'; say $string; # ¡Hola, Mundo!

In the first case, we assign the new value to the result of the method call. In the second case, we bind it to a scalar. The original string is modified after both assignments. Notice that the length of the replacement string may differ from the length of the replaced part.

`return-rw`

You can use `return-rw`

in places where you traditionally use `return`

. But with the longer variant, you actually return the object rather than the value.

sub my-value { state $value = 3.14;return-rw$value; } my-value++; say my-value; # 4.14

The `my-value++`

construct modifies the `state`

variable inside the function, so you increment it and with the next function call you get the same container with a modified value.

`take-rw`

A similar pair exists for `take`

. Use it together with `gather`

, in which case you return the container and you have full access to it, not only to its value.

Examine the following program, where the `gather`

block takes `$x`

and `$y`

.

my $x = 42; my $y = 2020; my $data := gather {take$x;take-rw$y; }; say $data; # (42 2020), is a Seq # $data[0]++; # Error $data[1]++; say "$x, $y"; # 42, 2021

(Notice that the result is bound to a scalar.)

You cannot modify the value gathered by `take $x`

, but you can do so with what was returned by `take-rw $y`

. For the second variable, the program prints its updates value.

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>The tasks reads:

Write a program to output the same number of PI digits as the size of your script. Say, if your program size is 10, it should print 3.141592653.

OK, I immediately have a few ideas:

- Just type the digits in the program and fit the width.
- Use some kind of formatting output.
- Compute the value of π and print it.

The first option contains a paradox. The program must keep need to keep all the digits that you need to print but you also need a printing instruction. So the file length will always be bigger. The only exception is when you are using REPL:

$ raku > 3.14 3.14

The second option is more promising. In Raku, there are at least `printf`

and `fmt`

. Let us see how many digits we can potentially use. The only place where you can see a substring `3.1415`

in the Rakudo sources seems to be the file gen/moar/CORE.c.setting:

my constant pi = 3.14159_26535_89793_238e0;

Looks like we have enough digits. Can we then print `π.fmt('%.20f')`

and see all of them?

> π.fmt('%.20f') 3.14159265358979300000

Oops. Not that promising any more. But let’s try to make the output shorter then. After a few attempts you get it:

> π.fmt('%.12f') 3.141592653590

Hmm, the width is perfect but there’s a zero in the last position? OK, let’s use an ASCII version to add a character and remove that zero:

> pi.fmt('%.11f') 3.14159265359

Ah, no, when switching from π to `pi`

, you need to *add* digits, not to remove them. And if you add, you’ll get zeroes. And did we forget that we are in the REPL, and for a real program in a file we need to add at least four characters to add `say`

?

OK, move on to the third option maybe? In the third option, we can use one of the known algorithms to compute the value of π to any arbitrary length, and then our program can in theory be as big as we want, including detecting its size by calling system functions.

Good one. But what if you just print π?

say π

Run this program and confirm that you get quite a few digits:

$ raku ch-1.raku

3.141592653589793

Aha, we’ve got a five-character program and 17 characters in the output. OK, let us just add some ‘useful’ noise to the code until it grows to the sam 18 characters.

print(pi ~ "\n");

Yes! Now there are exactly 17 characters. The program looks ugly but does the job and satisfies the conditions, so the task has been solved, congratulations!

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

The task reads as:

You are given an array `@A`

containing distinct integers. Write a script to find all leader elements in the array `@A`

. Print `(0)`

if none found. An element is leader if it is greater than all the elements to its right side.

For example:

```
Input: @A = (9, 10, 7, 5, 6, 1)
Output: (10, 7, 6, 1)
```

Before solving the task, let me notice that the last element of the input array is considered a leader element too, so there cannot be a case when you can’t find any leaders (well, except when the input data is empty).

My solution is here:

my @a = 9, 10, 7, 5, 6, 1; for @a.kv -> $i, $v { say $v if $v > all(@a[$i^..*]); }

The most attractive part of it is the use of the so-called all-junctions:

$v > all(@a[$i ^.. *])

No loops, no comparisons with individual elements. Just a single comparison that checks if *all* of the elements in the range pass the condition.

From the improvements in the syntax, you may want to make the solution a one-liner by using a postfix form of `for`

.

From the efficiency part, you should definitely go from the end of the array so that you do not re-scan the items on each iteration. This idea is illustrated in the next C++ program:

#include <iostream> #include <vector> using namespace std; int main() { vector<int> a = {9, 10, 7, 5, 6, 1}; auto max = a.back(); vector<int> leaders = {max}; for (auto i = a.rbegin(); i != a.rend(); i++) { if (*i > max) { max = *i; leaders.push_back(max); } } for (auto i = leaders.rbegin(); i != leaders.rend(); i++) cout << *i << endl; }

For the sample input array, both programs print the following:

10 7 6 1

You are given array `@A`

containing positive numbers and `@B`

containing one or more indices from the array `@A`

. Write a script to left rotate `@A`

so that the number at the first index of `@B`

becomes the first element in the array. Similary, left rotate `@A`

again so that the number at the second index of `@B`

becomes the first element in the array.

Example:

```
Input:
@A = (10 20 30 40 50)
@B = (3 4)
Output:
[40 50 10 20 30]
[50 10 20 30 40]
```

Well, let me reveal the solution in Raku

my @a = 10, 20, 30, 40, 50; my @b = 3, 4; say @a.rotate($_) for @b;

Enjoy the language! Start using it today!

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

Let me briefly remind the task and the solution in Raku. If you already have read my previous post, you can skip directly to the C++ solution. The solutions are given in the order of their creation.

You are given `m x n`

character matrix consists of `O`

and `X`

only. Write a script to count the total number of `X`

surrounded by `O`

only.

To illustrate the task, here is the picture where you can clearly see that there are only `O`

s around the lonely `X`

s.

My solution in the Raku programming language is the following:

my @matrix = < O O X >, < X O O >, < X O O >; # square matrix my @neighbours = ([X] (-1, 0, 1) xx 2).grep(*.all != 0); for ^@matrix X ^@matrix -> @coord { next if @matrix[@coord[0]][@coord[1]] eq 'O'; @coord.put if all( (@neighbours.map(* <<+>> @coord)). grep(0 <= *.all <= @matrix.end). map({ @matrix[$_[0]][$_[1]] eq 'O'; }) ); }

The program prints `0 2`

, which are the coordinates of the only lonely `X`

found in the given matrix. As this was the first solution, I allowed myself to simplify the task: the matrix here is assumed to be square.

The top-level idea in this program is to scan all cells of the matrix, and for each of them, look around to see the neighbours. There can be maximum 8 neighbours, but for the `X`

s on the sides or in the corners, not all neighbours exist. The real neighbours are `grep`

ped with the obvious condition that their coordinates do not take us outside of the matrix: `grep(0 <= *.all <= @matrix.end)`

.

Apart, I have the relative coordinates `@neighbours`

of all potential neighbouring cells, which I add to the coordinates of the current cell in the main loop: `@neighbours.map(* <<+>> @coord)`

. Then, I look if `all`

of the neighbours contain `O`

s, and if so, I print the coordinates of the current cell.

The main ingredients in this solution are the high-level routines such as `map`

, `grep`

, or cross- and reduction operators: `X`

, `[X]`

.

The C++ solution is, probably, the most straightforward classical approach but I added an optimisation which I find an interesting thing to mention.

Let me first show the whole solution.

#include <iostream> #include <vector> using namespace std; vector<int> test_move(vector<vector<char>> matrix, vector<int> current, vector<int> shift) { current[0] += shift[0]; current[1] += shift[1]; if (current[0] < 0 || current[0] >= matrix.size() || current[1] < 0 || current[1] >= matrix[0].size()) { return vector<int>(); } else { return current; } } int main() { vector<vector<char>> matrix = { {'O', 'O', 'O', 'X'}, {'O', 'X', 'O', 'O'}, {'O', 'O', 'O', 'X'} }; vector<vector<int>> neighbours = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; for (auto row = 0; row != matrix.size(); row++) { for (auto col = 0; col != matrix[0].size(); col++) { if (matrix[row][col] == 'O') continue; bool ok = true; for (auto neighbour : neighbours) { auto move = test_move(matrix, vector<int>{row, col}, neighbour); if (move.empty()) continue; if (matrix[move[0]][move[1]] == 'X') { ok = false; break; } } if (ok) cout << row << ", " << col << endl; } } }

First of all, there’s no restriction on the shape of the matrix. It can be square or rectangular.

The program uses some features of the recent C++ standards, so compile it with the `-std=c++17`

flag.

In the `main`

function, there are two nested loops to scan the matrix and touch every cell. If the current cell is `O`

, try the next one. Otherwise, test all the neighbours. I made a separate function `test_move`

which gets the coordinates of the current cell and the relative position of the neighbour. This function either returns the absolute coordinates of the neighbour or—if it does not exist—an empty vector.

The rest is simple. If the neighbour contains `X`

, we can stop here and state that the `X`

in the current cell is not a lonely one. If we managed to visit all existing neighbours and found no `X`

s there, the current `X`

is lonenly, so we print its coordinates.

The previous solution is good, but it can be made a little bit more efficient if you have many `X`

s as neighbours (of course, for such small matrices you will never notice any difference in the efficiency of a C++ program).

The idea is to replace already seen neighbouring `X`

s with `Y`

s. What does it give us? Imagine you have an `X`

in the top left corner of the matrix, and another _{1}`X`

at the first position of the first row. When you scan the matrix and test the neighbours of the first corner _{2}`X`

, you also visit _{1}`X`

. They are neighbours for each other, so neither of them can be called a lonely X. We can replace _{2}`X`

with _{2}`Y`

so that we immediately skip it when the main loop reaches that cell.

The changes touches the comparisons with `'O'`

and `'X'`

, and includes an extra assignment:

matrix[move[0]][move[1]] = 'Y';

For the given example case with corner neighbours, the new solution needs 30 tests while the original program makes 35 tests for the same input data.

vector<vector<char>> matrix = { {'X', 'O', 'O', 'X'}, {'O', 'O', 'X', 'O'}, {'X', 'O', 'O', 'X'} };

Examine the code of the modified solution on GitHub.

The next solution is really different. The matrix data is saved in the XML file:

<?xml version="1.0"?> <matrix> <row> <item>O</item> <item>X</item> <item>O</item> </row> <row> <item>O</item> <item>O</item> <item>O</item> </row> <row> <item>X</item> <item>O</item> <item>O</item> </row> </matrix>

The main program is an XSLT transformation document that describes how to handle the input data to generate the output, which is the list of coordinates of the lonely `X`

s:

1, 2 3, 1

To run the program, you need an XSLT processor, for example, from the libxslt2 library:

$ xsltproc ch-2.xslt ch-2.xml

The transformation scans all the items by first matching the `row`

nodes and then the `item`

s in them:

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="/matrix"> <xsl:apply-templates select="row"/> </xsl:template> <xsl:template match="row"> <xsl:apply-templates select="item"/> </xsl:template> . . . </xsl:stylesheet>

Then, there are two templates for the items. A generic template that matches all `item`

s and a specialised one for `X`

s. Having them both in the same file makes the first template matching only `O`

s, and as it does not contain any body, no output is generated for such cells.

<xsl:template match="item"/> <xsl:template match="item[text() = 'X']"> . . . </xsl:template>

Finally, the rule for the cell containing an `X`

:

<xsl:template match="item[text() = 'X']"> <xsl:variable name="row" select="count(../preceding-sibling::*) + 1"/> <xsl:variable name="col" select="position()"/> <xsl:variable name="lonely" select=" (not(/matrix/row[$row ]/item[$col - 1]) or /matrix/row[$row ]/item[$col - 1] = 'O') and (not(/matrix/row[$row ]/item[$col + 1]) or /matrix/row[$row ]/item[$col + 1] = 'O') and (not(/matrix/row[$row + 1]/item[$col ]) or /matrix/row[$row + 1]/item[$col ] = 'O') and (not(/matrix/row[$row - 1]/item[$col ]) or /matrix/row[$row - 1]/item[$col ] = 'O') and (not(/matrix/row[$row + 1]/item[$col + 1]) or /matrix/row[$row + 1]/item[$col + 1] = 'O') and (not(/matrix/row[$row - 1]/item[$col - 1]) or /matrix/row[$row - 1]/item[$col - 1] = 'O') and (not(/matrix/row[$row + 1]/item[$col - 1]) or /matrix/row[$row + 1]/item[$col - 1] = 'O') and (not(/matrix/row[$row - 1]/item[$col + 1]) or /matrix/row[$row - 1]/item[$col + 1] = 'O') "/> <xsl:if test="$lonely"> <xsl:value-of select="$row"/> <xsl:text>, </xsl:text> <xsl:value-of select="$col"/> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:template>

Here, visiting the neighbours is made via a couple of tests: first, we check if it exists: `not(/matrix/row[$row + 1]/item[$col + 1])`

and if so, we check its payload: `/matrix/row[$row + 1]/item[$col + 1] = 'O'`

.

The result of 8 such tests is saved in the `$lonely`

variable which is used in a Boolean test before generating the output. Thus, the program prints two coordinates on a line for each lonely X found in the source XML data.

Let us return to a procedural language and create a solution in Python 3.

matrix = [ ['X', 'O', 'O'], ['O', 'O', 'X'], ['X', 'O', 'O'], ] def is_O_cell(x, y): if 0 <= x < len(matrix[0]) and 0 <= y < len(matrix): return matrix[y][x] == 'O' else: return True x_cells = [ [col_i, row_i] for row_i, row in enumerate(matrix) for col_i, cell in enumerate(row) if cell == 'X' ] for x_cell in x_cells: x, y = x_cell if is_O_cell(x , y + 1) and \ is_O_cell(x , y - 1) and \ is_O_cell(x + 1, y ) and \ is_O_cell(x - 1, y ) and \ is_O_cell(x + 1, y + 1) and \ is_O_cell(x + 1, y - 1) and \ is_O_cell(x - 1, y + 1) and \ is_O_cell(x - 1, y - 1): print(f"Lonely X at position ({x}, {y}).")

In this solution, the `is_O_cell(x, y)`

function checks if the cell at the given position `x, y`

contains an `O`

or is outside of the matrix. In the latter case, it returns `True`

. Instead of rejecting the neighbouring cell, we can just pretend that it is a desired neighbour—the same as the one with `O`

in it.

The key thing in this solution in Python is the way I select the cells with `X`

s from the given matrix. It uses list comprehension with two nested loops:

x_cells = [ [col_i, row_i] for row_i, row in enumerate(matrix) for col_i, cell in enumerate(row) if cell == 'X' ]

The `x_cells`

variable now contains the coordinates of the cells from which we will visit the neighbours. Visiting neighbours is a Boolean chain of calling `is_O_cell`

around the current `X`

cell.

This solution is actually an interactive solution that you can play with in a browser. This is the solution which you can try even if you have no compilers installed.

Let me skip the whole code this time and show the main two functions in JavaScript. You can see the rest on GitHub.

Instead of `O`

s and `X`

s, the content of a cell is represented by the state of the checkbox in it.

When the page loads or when you press the button, the script generates an HTML code for drawing the matrix with checkboxes and necessary data attributes `data-x`

and `data-y`

that keep the coordinates, and the `onclick`

attribute to trigger the function `update_lonely()`

every time you click on a cell.

function update_lonely() { let cells = document.getElementById('Shape').getElementsByTagName('input'); let neigbours = [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [-1, -1], [1, -1], [-1, 1]]; for (let i = 0; i != cells.length; i++) { cells[i].parentNode.className = ''; if (!cells[i].checked) continue; let x = parseInt(cells[i].getAttribute('data-x')); let y = parseInt(cells[i].getAttribute('data-y')); let is_ok = true; for (let c = 0; c != neigbours.length; c++) { if (!test_cell(x + neigbours[c][0], y + neigbours[c][1])) { is_ok = false; break; } } if (is_ok) { cells[i].parentNode.className = 'lonely'; } } }

Here, the `neighbours`

array keeps the relative coordinates of the neighbours as in some of the other programs we saw earlier. Then, we scan the cells and with the help of the `test_cell`

function determine whether the cell is outside of the matrix or its checkbox is not checked, which is equivalent to `O`

in other solutions.

function test_cell(x, y) { if (x < 0 || y < 0 || x >= w || y >= h) { return true; } else { let cell = document.querySelector( '#Shape tr td input[data-x="'+ x + '"][data-y="' + y + '"]' ); return !cell.checked; } }

In this program, you can see a number of web-specific things such as setting classes to change the visual representation of the result or accessing matrix data using CSS selectors.

Do you think there are no more ideas for a fresh solution? There are!

Here is a program in Perl that uses pattern matching to find the lonely `X`

s.

my @matrix = ( [qw( O O O X )], [qw( X O O O )], [qw( O X O X )], ); for (@matrix) { unshift @$_, 'O'; push @$_, 'O'; } unshift @matrix, [map {'O'} 1..scalar(@{$matrix[0]})]; push @matrix, [map {'O'} 1..scalar(@{$matrix[0]})]; my $matrix = join '', map({join '', @$_} @matrix); my $width = scalar(@{$matrix[0]}); my $gap = '.' x ($width - 3); my $pattern = "OOO${gap}OXO${gap}OOO"; for my $pos (0 .. length($matrix) - length($pattern)) { next unless substr($matrix, $pos) =~ /^$pattern/; my $y = int($pos / $width); my $x = $pos - $y * $width; say "$y, $x"; }

Before the main part of the code, we modify the matrix to surround it with `O`

s. So, for the given example, the matrix becomes the following:

O O O O O O O O O O X O O X O O O O O O X O X O O O O O O O

Remember how we returned `True`

for the cells outside of the matrix? Now you can see that this is exactly what happens if you simply extend the matrix and fill it with zeroes that do not change the status of lonely Xs.

The second preparation step is to make a single string out of the matrix:

OOOOOOOOOOXOOXOOOOOOXOXOOOOOOO

Finally, let’s make a regex. What we need is to find an `X`

which is surrounded by `O`

s. Or, in other words, there should be three `OOO`

above and below it, and one `O`

right before and right after. In-between, we can have any characters, which you can express with a series of dots in a regular expression:

my $gap = '.' x ($width - 3); my $pattern = "OOO${gap}OXO${gap}OOO";

With the given sample matrix, the regex takes the following shape:

OOO...OXO...OOO

The last step is to apply the regex at every position of the `$martix`

string and then convert the linear position to a pair of `x`

and `y`

if the regex matched at that position.

next unless substr($matrix, $pos) =~ /^$pattern/; my $y = int($pos / $width); my $x = $pos - $y * $width;

And that’s it!

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

You are given `m x n`

character matrix consists of `O`

and `X`

only. Write a script to count the total number of `X`

surrounded by `O`

only. Print `0`

if none found.

So, there’s a matrix, and you need to find the `X`

s which are surrounded by `O`

s. Let me illustrate a couple of examples:

My solution simplifies the task in two aspects. First, I assume that the matrix is square (as in the demonstrated examples). Second, I do not print `0`

if nothing found (as many Unix command-line tools would do). Nevertheless, I am striving for showing the code.

my @matrix = < O O X >, < X O O >, < X O O >; # square matrix my @neighbours = ([X] (-1, 0, 1) xx 2).grep(*.all != 0); for ^@matrix X ^@matrix -> @coord { next if @matrix[@coord[0]][@coord[1]] eq 'O'; @coord.put if all((@neighbours.map(* <<+>> @coord)).grep(0 <= *.all <= @matrix.end).map({ @matrix[$_[0]][$_[1]] eq 'O'; })); }

I believe I wanted to use as many non-standard things as I could, and I am sure there is still room to pack the loops or the checks to even more of similar constructions. On the other hand, I think the result is mostly worth examining rather than entering the daily programming practice.

OK, let’s see how this program works.

The `@matrix`

is an array that contains three lists. Use the `dd`

routine to see the types:

dd @matrix; # Array @matrix = [("O", "O", "X"), ("X", "O", "O"), ("X", "O", "O")]

dd @matrix[0]; # List @matrix = $("O", "O", "X")

Then, I want to make a plan to visit all the neighbours. On an infinite board, there are nine neighbours for every cell. So, I am making a map of movements:

my @neighbours = ([X] (-1, 0, 1) xx 2).grep(*.all != 0);

To visit the neighbours, we need to change one or both of the *x* and *y* coordinates to +1 or −1. The construct `[X] (-1, 0, 1) xx 2`

gives us the following directions:

((-1 -1) (-1 0) (-1 1) (0 -1) (0 0) (0 1) (1 -1) (1 0) (1 1))

To exclude the current cell `(0, 0)`

, a restriction is added: `.grep(*.all != 0)`

.

OK, next, I am visiting all the cells of the original matrix. The loop scans all the cells as `^@matrix X ^@matrix`

, which for the sample case means `^3 X ^3`

, which is:

((0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2))

On each iteration, I am taking a pair of coordinates from this sequence in the `@coord`

array and immediately skip the loop body if the current cell does not keep `X`

:

next if @matrix[@coord[0]][@coord[1]] eq 'O';

Then, from a given position `@coord`

, let’s visit the neighbours. So, we need to compute their coordinates too:

@neighbours.map(* <<+>> @coord)

This construction produces the coordinates of the neighbouring cells. For example, for the central position `(1, 1)`

, the result is the following:

((0 0) (0 1) (0 2) (1 0) (1 2) (2 0) (2 1) (2 2))

For the cells on the border or in the corners, the coordinates of the neighbours will be either negative or bigger than the size of the matrix. So, let’s filter them out: `.grep(0 <= *.all <= @matrix.end)`

.

So, we now have a list of all existing neighbours, so let’s see if they contain `0`

:

.map({ @matrix[$_[0]][$_[1]] eq 'O'; }));

Almost there. Now, surround what we have with `all(. . .)`

and print the result only if all of the neighbours pass the condition: `@coord.put if . . .`

.

And that’s it. Run the program with different matrices and see what it prints. For the examples displayed on the image in the beginning of this post, the program prints:

$ raku ch-2.raku 0 2 $ raku ch-2.raku 0 2 2 3

* * *

**Update:** Explore my other solutions in C++, XSLT, JavaScript, Python, and Perl in the next post.

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

The task today is:

You are given a positive integer `$N`

. Write a script to find out all possible combination of Fibonacci Numbers required to get `$N`

on addition. You are NOT allowed to repeat a number. Print 0 if none found.

Let me immediately simplify the task. First of all, there are only two repeated numbers in the Fibonacci sequence itself: 1, 1, 2, 3, 5, …. So, we can start from the second number to remove the potential duplicate number. Second, it looks like you can represent *any* positive integer with a sum of Fibonacci numbers. I have the feeling because of the nature of the sequence, but you can also prove it. So, no need to check if you can find the solution.

Finally, here is my solution:

my $n = @*ARGS[0] // 42; my @fib = 1, 2, * + * ...^ * > $n; "$_.join(' + ') = $n".put for @fib.combinations.grep(*.sum == $n);

We take `$n`

from command line and generate a sequence that does not exceed that number. Notice that unlike a proper Fibonacci sequence, I force it to start with the numbers 1 and 2.

Then, the numbers are mixed in all possible combinations and finally filtered so that their sum is correct.

And that’s it. Run the program with different arguments to see the results.

$ raku ch-1.raku 22 1 + 21 = 22 1 + 8 + 13 = 22 1 + 3 + 5 + 13 = 22

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

Before the details disappear from our memories, I want to write the story of how we were doing it from the Day 1 till the last day when our rooms existed.

The table of contents below is a draft script of what I am going to write about but it will definitely change along the way, so stay tuned.

The idea

Be the first to open

Searching for the office place

The Zombie room

Electronics

Flooding and the plantation

The first employee

The Flood room

Feeding families

Leaking roof

Getting the stairs

The Black Hole

Hosting parties

The Cat

The sleeping guy

Fire inspection

Sold

Coronavirus

]]>Despite that solution perfectly works, I wasn’t satisfied with it and wanted a more Raku-ish code. Here is the next iteration of it.

my @hist = 3, 2, 3, 5, 7, 5; my $max = 0; for (^@hist).combinations(2) -> ($x, $y) { $max = max($max, min(@hist[$x .. $y]) * ($y - $x + 1)); } say "The area of a biggest rectangle is $max.";

If you looked at the output of the previous variant, you may have noticed that the ranges in the loop resemble the number combinations from Task 1 of Week 67. And that’s the hart of this solution:

(^@hist).combinations(2)

This simple line gives us what we need: all the possible sub-histograms (well, maybe except the single-column ones):

0 .. 1 0 .. 2 0 .. 3 0 .. 4 0 .. 5 1 .. 2 1 .. 3 1 .. 4 1 .. 5 2 .. 3 2 .. 4 2 .. 5 3 .. 4 3 .. 5 4 .. 5

The rest is simple. Find the area of a rectangle by multiplying the width of the window by the maximum common height of the histogram bins in it:

$max = max($max, min(@hist[$x .. $y]) * ($y - $x + 1));

Run the program to confirm it works and prints the correct result:

$ raku ch-2a.raku The area of a biggest rectangle is 15.

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

You are given an array of positive numbers `@A`

.

Write a script to find the largest rectangle histogram created by the given array.

The following visualisation illustrates the task. The goal is to build a histogram with the values from the input and to find the rectangle with the maximum area.

My current solution is quite straightforward. Just scan all the possible positions and all possible widths of the potential rectangle, find its maximum possible height and compute the area.

my @hist = 3, 2, 3, 5, 7, 5; my $max = 0; my @max; for ^@hist -> $start { for $start ^..^ @hist -> $end { my $area = min(@hist[$start .. $end]) * (1 + $end - $start); say "$start..$end = $area"; if $area > $max { $max = $area; @max = $start, $end; } } } say "The biggest rectangle is between the columns @max[0] and @max[1] and its area is $max.";

* * *

On GitHub, you’ll also find my C++ solution to this task.

Update: a more idiomatic Raku solution.

→ GitHub repository

→ Navigation to the *Raku challenges* post series

You are given a set of coins `@C`

, assuming you have infinite amount of each coin in the set.

Write a script to find how many ways you make sum `$S`

using the coins from the set `@C`

.

My solution is a kind of a two-liner:

my @coins = 1, 2, 4; my $sum = 6; my @wallet; @wallet.append: $_ xx ($sum div $_) for @coins; .say for @wallet.combinations.unique(:as(*.Str)).grep({$sum == [+] $_});

The `@coins`

array keeps the types of available coins. Then, we fill the `@wallet`

so that we have enough real coins to make the `$sum`

by using only a single kind of them (if that is possible at all).

For the given example, the `@wallet`

contains the following collection:

[1 1 1 1 1 1 2 2 2 4]

The next step is to find all possible `unique`

`combinations`

of the coins from the wallet and take only those, whose sum is `$sum`

.

To take only unique combinations, I am calling `.unique(:as(*.Str))`

which treats them as a string. This step can possibly be made more optimal.

To filter the combinations, a `grep`

method is used, where the reduction operator is used to compute the sum: `.grep({$sum == [+] $_})`

.

With the above input, the program prints the following combinations of coins that give the required amount:

(2 4) (1 1 4) (2 2 2) (1 1 2 2) (1 1 1 1 2) (1 1 1 1 1 1)

* * *

→ GitHub repository

→ Navigation to the *Raku challenges* post series

This is probably the shortest way to toss a coin in Raku (or flip a coin if you wish):

sayBool.pick;

You get either `False`

or `True`

. That simple.

Alternatively, you can use `roll`

:

sayBool.roll;

If you need to make more than one experiment, tell the number you need:

say Bool.roll(7);

The method returns a sequence of seven random Booleans in this case:

(False True True False False True False)

Try solving the following simple task without using any variables:

*Generate a random integer below 20 and print it if it was a prime number.*

A typical solution would require a variable to keep the generated number:

my $n = 20.rand.Int; say $n if $n.is-prime;

In Raku, you can set a topic and use it to do more than one action with it. For example, using `given`

:

.is-prime && .saygiven20.rand.Int;

The same effect is achieved via `with`

or `for`

:

.is-prime && .sayfor20.rand.Int; .is-prime && .saywith20.rand.Int;

In the above examples, we are calling methods directly on the topic variable but you are free to use the `$_`

variable explicitly.

Here’s another task:

*In an array of random integers, find and print the maximum even number but only if it is bigger then 5, otherwise print 0.*

So, let’s prepare the data first:

my @t = (^10).roll(5); say @t;

A possible solution without using temporary variables could look like this:

say @t.grep(* %% 2).max > 5 ?? @t.grep(* %% 2).max !! 0;

Unfortunately, we compute the value twice here. Let’s avoid that by setting a topic:

with@t.grep(* %% 2).max { say $_ > 5 ?? $_ !! 0 }

Of course, a postfix form is also possible:

say $_ > 5 ?? $_ !! 0with@t.grep(* %% 2).max;

Or:

say $_ > 5 ?? $_ !! 0given@t.grep(* %% 2).max;

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>`min`

function. Occasionally, also on `max`

, but the whole story is well applicable to both of them. Some of the elements can also be used with other functions.
`min`

This is not a trivial question, actually Let’s take an array with some integers, both positive and negative, and find the minimum value using different forms of the call:

my @data = 3, -2, 6, 1, 5; say min @data; # -2 say min(@data); # -2 say @data.min; # -2 say @data.min(); # -2

As you can see, both a standalone function and a method are available.

But that’s not it. You can use a reduction operator with the `min`

function in it:

say [min] @data; # -2

According to the definition, this is equivalent to the following chain, which you can also use (but why):

say @data[0] min @data[1] min @data[2] min @data[3] min @data[4]; # -2

`min`

of nothingWhat if you apply `min`

to an empty array? The result is logical but maybe not always intuitively straightforward.

my @a; say @a.min; #Inf

Indeed, if you want to find a minimum element in the loop, you usually start with the first element and compare the next element with it. If you start with infinity, you do not have to make any special use of the first element to warm up the loop.

The same happens to `()`

, `Empty`

, `Nil`

, or `Any`

:

say ().min; # Inf say Empty.min; # Inf say Nil.min; # Inf say Any.min; # Inf

You can find more similar examples, but let me mention that with `max`

, you get `-Inf`

:

say @a.max; # -Inf say ().max; # -Inf say Empty.max; # -Inf say Nil.max; # -Inf say Any.max; # -Inf

`min`

with `by`

The `min`

routine accepts the named argument `:by`

, which you can use to modify the value before the function actually makes the comparison. For example, with our initial data array, let us find the absolute minimum value:

my @data = 3, -2, 6, 1, 5; say min(@data, :by( { abs($_) } )); # 1

I added some air around the braces and parentheses for better visibility, but you can also use the `WhateverCode`

block to increase it further:

say min(@data, by => -*); # 6

In this example, all the elements are negated and `min`

serves as `max`

.

N.B.! In the case of using a method, the only optional argument `&by`

is a positional argument, so you can’t pass it as a named parameter. Just pass the code:

say @data.min({abs($_)}); # 1 say @data.min: {abs($_)}; # 1 say @data.min: -*; # 6

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>Reduction operators are quite useful and allow to code the whole algorithm with just a few characters, as you do to compute a factorial, for example:

say [*] 1..5; # 120

Here, the computation is equivalent to `1 * 2 * 3 * 4 * 5`

and only the result of it is returned.

But if you also want to get factorials of smaller numbers, or, in other words, to keep the intermediate results of enrolling the data and applying the operator, just add a backslach:

say [\*] 1..5; # (1 2 6 24 120)

The result is evaluated lazily, so we can have an array of factorials for any integer:

my @fact = [\*] 1..*; say @fact[^10]; # (1 2 6 24 120 720 5040 40320 362880 3628800) say @fact[20]; # 51090942171709440000

Let me demonstrate another interesting use case of the triangular metaoperator. This time, the main operator is `,`

— the infix comma that makes the lists.

.say for [\,] ^5;

This program prints the following lines:

(0) (0 1) (0 1 2) (0 1 2 3) (0 1 2 3 4) (0 1 2 3 4 5)

Tell me if you know the shorter way to get that.

For example, let’s compute the sums of the even integers below 10:

say [+] $_ for [\,] 2, 4 ...^ 10;

The program prints the values 2, 6, 12, 20, which are the sums of the following rows:

# 2 = 2 # 6 = 2 + 4 # 12 = 2 + 4 + 6 # 20 = 2 + 4 + 6 + 8

* * *

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>In the two Raku solutions below, you can see how you can use the built-in `Bag`

data type.

*You are given an array of integers of size $N. Write a script to find the majority element. If none found then print -1. The majority element in the list is the one that appears more than floor(size_of_list/2).*

OK, fine, let’s take a sample array of integers:

my @a = 1, 2, 2, 3, 2, 4, 2;

Here, `2`

is the major element as it appears 4 times and it is more than the half of the length. The only missing thing in the task is what if we have two or more such items? I decided to limit myself to the first such item only.

The traditional approach to count the items in Perl would require using a hash, but in Raku there’s another useful data type: `Bag`

. It is a kind of a hash but if you create it from a list, its values are the number of repetitions of each item:

> dd (1, 2, 2, 3, 2, 4, 2).Bag (3=>1,1=>1,2=>4,4=>1).Bag

So, we can count all the elements in a single go by converting an array to a bag. Then, sort it by the number of repetitions and take the first item.

my $most-frequent = (@a.Bag.sort: -*.value)[0];

`-*.value`

sorts the bag in descending order. (Alternatively, we could sort with `*.value`

and then take the last item `[*-1]`

.)

The main part of the problem is solved, just choose what to print now: either the element or `-1`

. This check is actually longer than the above one-liner

say $most-frequent.value > @a.elems / 2 ?? $most-frequent.key !! -1;

For the given array, this program prints `2`

:

$ raku ch-1.raku 2

With another example of input data, `1, 3, 1, 2, 4, 5`

, the result is `-1`

as none of the elements is major.

Here is my solution in another great language of all times, C++.

#include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() { vector<int> data = {1, 2, 2, 3, 2, 4, 2}; // vector<int> data = {1, 3, 1, 2, 4, 5}; map<int, int> frequency; int max_frequency = 0; int major = 0; for (auto x : data) { if (++frequency[x] > max_frequency) { max_frequency = frequency[x]; major = x; } } cout << (max_frequency > data.size() / 2 ? major : -1) << endl; }

It uses a range-based `for`

loop, so you need to compile the program against the new C++ standard:

$ g++ --std=c++17 ch-1.cpp

In this program, a map `frequency`

keeps the number of occurrences of each unique integer, and while we are building this map, we are also keeping track of the maximum value `max_frequency`

and its corresponding major element `major`

, so there’s no need to scan the map again (even if I wanted to use some kind of sort algorithm first).

The second task reads as:

*You are given a string $S. Write a script to print the series of first non-repeating character (left -> right) for the given string. Print # if none found.*

*Example. Input: $S = ‘ababc’. Output: ‘abb#c’Pass 1: “a”, the FNR character is ‘a’Pass 2: “ab”, the FNR character is ‘b’Pass 3: “aba”, the FNR character is ‘b’Pass 4: “abab”, no FNR found, hence ‘#’Pass 5: “ababc” the FNR character is ‘c’*

It sounds clear but the example is controversial. For the string `ab`

, the first non-repeating character is `a`

but not `b`

. A direct question and the answer did not made it any more clear, so I guess you should read it as *from right to left*. (There’s an update now but still not clear.) Or something else was meant, which I cannot decipher from the example.

Let me just demonstrate the solution. I added `reverse`

to make the result matching the given example.

my $s = 'ababc'; # my $s = 'xxyyzzyx'; for 1..$s.chars -> $pos { my $substr = $s.substr(0, $pos).join; print "In '$substr': "; my $b = bag $substr.comb; say $substr.comb.reverse.first({$b{$_} == 1}) // '#'; }

Nevertheless, notice how converting to a `Bag`

is used here:

my $b = bag $substr.comb;

For example, for the string `abac`

, the bag will have the following content:

> bag 'abac'.comb Bag(a(2), b, c)

So, we just counted all the letters in the string and prepared a table of their usage.

The program prints the following output:

$ raku ch-2.raku In 'a': a In 'ab': b In 'aba': b In 'abab': # In 'ababc': c

→ GitHub repository

→ Navigation to the *Raku challenges* post series

An interesting way of providing the default values to all of the parameters of the `MAIN`

function. Just define a multi-version that takes no arguments and calls a suitable version with the parameters you want.

multi subMAIN(){MAIN('User'); } multi sub MAIN(Str $name, Str $greeting = 'Hello') { say "$greeting, $name!"; }

Now, running a program without the arguments gives some meaningful result.

$ raku default-main.raku Hello, User! $ raku default-main.raku John Hello, John!

You can combine this method with regular default values of the arguments. If there is no sense to run a program with no parameters, make sure you have a descriptive USAGE example.

The `BEGIN`

phaser can be used to print a message before the program even starts running. This may be handy, for example, if you have a few different `MAIN`

functions and want to have a common message for all of them.

The below (rather artificial) program prints a message even if the main code fails.

BEGIN {say 'This program prints the result of division by zero.';}multi sub MAIN() { say 42/0; } multi sub MAIN(Int $n) { say $n / 0; }

Find the code of this issue on GitHub and browse for more Raku Pearls.

]]>