# Perl Weekly Challenge 64: matrixes and linked lists

One way to let me improve my knowledge about Raku (aka Perl 6) is to implement programs in it. Unluckily, I don’t have any production code to implement in Raku yet (sob!). So, why not try solving the Perl Weekly Challenge tasks?In the following, the assigned tasks for Challenge 64.

### CORONAVIRUS

We are experiencing another increase in the number of hospitalized people.I’m pretty optimistic about the possible solution, but it is still a strange context to live into.

### Olivia

The vet said she has recovered a lot, and probably we need to wait another three months for see her jumping.We really hope, let’s say it is strange to have her inside house all the day during summer.

### Eyes

This is a realy mind-brain.The last check emphasized that the pressure is still very high, so we decided to increase again the medications and to proceed with a laser therapy that, quite frankly, I don’t thinkg will produce any result.

It is almost sure I’m going to be hospitalized, the matter now is

*when*.

## PWC 68 - Task 1

The first task was about*zeroing*columns and rows of a matrix where a zero already exists: if a row or column has a zero, then zero all elements in the same row and column.

Instead of working with a matrix, I assumed the matrix would come from the command line as a flat array. This makes a little harder to compute the offset for each element in rows and columns. Anyway, instead of doing a brute-force loop over all the cells, I decided to

`grep`

the array for zeros and keep asde the indexes. Those indexes are absolute (the matrix is a one dimension array) and need to be converted into `$row`

and `$column`

, then it is quite simple to zero the row and column in the array.
```
sub MAIN( Int $m, Int $n, *@incoming-matrix ) {
my @matrix = @incoming-matrix;
"Original matrix was ".say;
print-matrix( @incoming-matrix, $m, $n );
my @zeros = @matrix.grep( * == 0, :k );
for @zeros -> $zero-at {
my ( $row, $column ) = ( $zero-at - 1 / $m ).Int, ( $zero-at % $n ).Int;
@matrix[ $_ + $row ] = 0 for 0 ..^ $m; # zero the rows
@matrix[ $column + ( $_ * $m ) ] = 0 for 0 ..^ $n; # zero the columns
}
"Transformed matrix is".say;
print-matrix( @matrix, $m, $n );
}
```

The utility function

`print-matrix`

is as simple as follows:
```
sub print-matrix( @matrix, $m, $n ){
say "----" ~ "--" x $m;
for 0 ..^ $m -> $row {
print "| ";
for 0 ..^ $n -> $column {
print "@matrix[ ( $row * $m ) + $column ] ";
}
say " |";
}
say "----" ~ "--" x $m;
}
```

Invoking this program produces a result similar to the following one:

```
% raku ch-1.p6 3 3 1 0 1 1 1 1 1 0 1
Original matrix was
----------
| 1 0 1 |
| 1 1 1 |
| 1 0 1 |
----------
Transformed matrix is
----------
| 0 0 0 |
| 1 0 1 |
| 0 0 0 |
----------
```

## PWC 68 - Task 2

Task two required to re-order a linked list by popping the last element and placing after the first one, the second-to-last to be placed as the third one and so on. First of all, I declared a very dummy`Node`

class:
```
class Node {
has Str $.value is rw;
has Node $.next is rw;
}
```

Nothing fancy or complex, just to work with the list. The list has been initialized with a loop as follows:

```
sub MAIN() {
# build the list
my Node $root = Node.new( :value( "L0" ) );
my Node $current-node = $root;
for 0 ^..^ 10 {
$current-node.next = Node.new( :value( "L$_" ) );
$current-node = $current-node.next;
}
```

Now that I have a list to work with, let’s convert into a flat array following the current links:

```
# convert into an array
my @nodes;
$current-node = $root;
while ( $current-node ) {
@nodes.push: $current-node;
$current-node = $current-node.next;
}
```

Now it is possible to build a

*clone array*where the elements are shifted by their position depending on an index that is tied to the length of the array itself:

```
# sort into another array
my @new-nodes;
for 0 ..^ @nodes.elems / 2 {
"switching elements $_ and { @nodes.elems - $_ - 1 }".say;
@new-nodes.push: @nodes[ $_ ];
@new-nodes.push: @nodes[ @nodes.elems - $_ -1 ];
}
```

In the end,

`@new-nodes`

will have the desired order of the nodes.
It is now turn to adjust the nodes with the new links following the array:
```
# now adjust linked references
for 0 ..^ @new-nodes.elems - 1 {
@new-nodes[ $_ ].next = @new-nodes[ $_ + 1 ];
}
@new-nodes[ @new-nodes.elems - 1 ].next = Nil;
```

And all the nodes have now the correct link to the switched elements.