### Perl Weekly Challenge: Week 53

#### Challenge 1:

Rotate MatrixWrite a script to rotate the following matrix by given 90/180/270 degrees clockwise.

`[ 1, 2, 3 ] [ 4, 5, 6 ] [ 7, 8, 9 ]`

For example, if you rotate by 90 degrees then expected result should be like below

`[ 7, 4, 1 ] [ 8, 5, 2 ] [ 9, 6, 3 ]`

This time I will do the Raku version first. The `MAIN()`

sub just checks that the
`$angle`

is a valid value, calls the `rotate()`

routine below and displays the result so
I won't show it here. `rotate()`

looks like this:

```
sub rotate(Int $angle) {
```

I suppose I could have made the matrix a parameter but the problem description only specifies one particular kind so I hardcoded it as an array of arrays.

```
my @matrix =
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ],
;
```

I assigned the length of `@matrix`

to a variable because we will be using it several
times later. It is called `$side`

because this is the length of a side the matrix.
As a result my code will not work properly with a "rectangular" (i.e. 3 x 4 or 7 x 5)
matrix. As ours is "square" this doesn't matter for now.

```
my $side = @matrix.elems;
```

If `$angle`

is 90° we need to rotate the matrix once, if 180° twice, and if
270° three times.

```
for (0 ..^ $angle / 90) {
```

I created a new matrix and transposed the elements from the old one into it and then replaced the old one with it.

```
my @newMatrix;
for (0 ..^ $side) -> $row {
for (0 ..^ $side) -> $col {
@newMatrix[$col].unshift(@matrix[$row][$col]);
}
}
@matrix = @newMatrix;
```

While this works, I had a dim memory in the corner of my mind that there is a way to rotate a matrix in place. Some googling later, I came up with this:

```
for (0 ..^ $side / 2) -> $row {
for ($row ..^ $side - $row - 1) -> $col {
my $temp = @matrix[$row][$col];
@matrix[$row][$col] = @matrix[$side - 1 - $col][$row];
@matrix[$side - 1 - $col][$row] =
@matrix[$side - 1 - $row][$side - 1 - $col];
@matrix[$side - 1 - $row][$side - 1 - $col] =
@matrix[$col][$side - 1 - $row];
@matrix[$col][$side - 1 -$row] = $temp;
}
}
```

Finally we return the rotated matrix.

```
}
return @matrix;
}
```

This is the Perl version of `rotate()`

.

```
sub rotate {
my ($angle) = @_;
my @matrix = (
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ],
);
my $side = scalar @matrix;
for (1 .. $angle / 90) {
for my $row (0 .. ($side / 2) - 1) {
for my $col ($row .. ($side - $row - 1) - 1) {
my $temp = $matrix[$row][$col];
$matrix[$row][$col] = $matrix[$side - 1 - $col][$row];
$matrix[$side - 1 - $col][$row] =
$matrix[$side - 1 - $row][$side - 1 - $col];
$matrix[$side - 1 - $row][$side - 1 - $col] =
$matrix[$col][$side - 1 - $row];
$matrix[$col][$side - 1 -$row] = $temp;
}
}
}
return @matrix;
}
```

#### Challenge 2:

Vowel StringsWrite a script to accept an integer

1 <= N <= 5that would print all possible strings of sizeNformed by using only vowels (a, e, i, o, u).The string should follow the following rules:

‘a’ can only be followed by ‘e’ and ‘i’.

‘e’ can only be followed by ‘i’.

‘i’ can only be followed by ‘a’, ‘e’, ‘o’, and ‘u’.

‘o’ can only be followed by ‘a’ and ‘u’.

‘u’ can only be followed by ‘o’ and ‘e’.

For example, if the given integer N = 2 then script should print the following strings:

`ae ai ei ia io iu ie oa ou uo ue`

Once again, I'm describing my Raku solution first, and once again only showing
the main part, the `generate()`

routine.

```
sub generate(Int $n) {
```

I encoded the generation rules as a hash whose keys are vowels and values are the valid succeeding characters.

```
my %rules = (
a => [< e i >],
e => [< i >],
i => [< a e o u >],
o => [< a u >],
u => [< e o >]
);
my @generated;
for (1 .. $n) -> $i {
```

If `$n`

is 1, there is no need to do anything except list out the vowels. I didn't strictly
speaking need to sort this list but it looks better if the results are in alphabetical order.

```
if ($i == 1) {
@generated = %rules.keys.sort;
```

If `$n`

is 2 or more, we repeatedly replace each element in `@generated`

(which
at the start consists of five one-character strings: `'a', 'e', 'i', 'o', 'u'`

because of the `$n = 1`

case.) with one or more strings consisting of a copy of
the existing element plus a value from the `%rules`

hash where the key is the last
character of the existing element.

Note the `|`

character in the returned value of the outer `map()`

. This is so
the result we are adding to `@generated`

is "flattened" into a individual values rather
than a single array.

```
} else {
@generated = @generated.map({
my $e = $_;
| %rules{$e.substr(*-1, 1)}.values.map({ $e ~ $_; });
});
}
}
return @generated;
}
```

Here is the Perl version of the `generate()`

routine.

```
sub generate {
my ($n) = @_;
my %rules = (
a => [qw/ e i /],
e => [qw/ i /],
i => [qw/ a e o u /],
o => [qw/ a u /],
u => [qw/ e o /]
);
my @generated;
for my $i (1 .. $n) {
if ($i == 1) {
@generated = sort keys %rules;
} else {
@generated = map {
my $e = $_;
map { $e . $_; } @{ $rules{substr $e, -1, 1} };
} @generated;
}
}
return @generated;
}
```