Wave arrays, a solution in Raku

For the given array of integers, rearrange the items so that the shape of the resulting array resembles the wave, that is, the second item is less or equals than the first one, the third item is bigger or equals to the second, then again a smaller number, then a bigger, and so on.

This is a solution to the Perl Weekly Challenge from Week 55, task 2.

For the given array of integers, rearrange the items so that the shape of the resulting array resembles the wave, that is, the second item is less or equals than the first one, the third item is bigger or equals to the second, then again a smaller number, then a bigger, and so on.

A first solution for an array of the fixed size is straightforward:

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

.say for grep {$_[0] >= $_[1] <= $_[2] >= $_[3]}, @a.permutations;

Here, all possible combinations of the given numbers are generated, and the filter checks which combinations pass the wave shape:

$ raku ch-2.raku 
(2 1 4 3)
(3 1 4 2)
(3 2 4 1)
(4 1 3 2)
(4 2 3 1)

In the second variant, a separate checker function is introduced, which checks the value of each number against its neighbours:

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

.say for grep &wave, @a.permutations;

sub wave(@a) {
    all(
        (@a[$_] >= @a[$_ + 1] for 0, 2 ... @a.elems - 2)
    ) &&
    all(
        (@a[$_] <= @a[$_ + 1] for 1, 3 ... @a.elems - 2)
    );
}

Run it with a different array, say, with 5 elements as in the example:

$ raku ch-2a.raku 
(2 1 4 3 5)
(2 1 5 3 4)
(3 1 4 2 5)
(3 1 5 2 4)
(3 2 4 1 5)
(3 2 5 1 4)
(4 1 3 2 5)
(4 1 5 2 3)
(4 2 3 1 5)
(4 2 5 1 3)
(4 3 5 1 2)
(5 1 3 2 4)
(5 1 4 2 3)
(5 2 3 1 4)
(5 2 4 1 3)
(5 3 4 1 2)

GitHub repository
Navigation to the Raku challenges post series

Leave a Reply

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