# Perl Weekly Challenge 088

Another week, another challenge and chance to practice Perl and Python programming skills.

#### Challenge 1 - Array of Product:

You are given an array of positive integers `@N`.

Write a script to return an array `@M` where `\$M[i]` is the product of all elements of `@N` except the index `\$N[i]`.

This one was quite straightforward. My first idea was to loop through the array and calculate the products using slicing of the array.

Then I realized it is easier to calculate the product once and then just divide it by each number.

1. Calculate the Product:

Perl - using product function from List::Util:

``my \$product = product(@\$in_arr);``

Python:

``````product = 1
for i in in_arr:
product *= i``````
1. Push the result to the return array.

Perl:

``push @out_arr, int(\$product / \$_) for (@\$in_arr);``

Python:

``````for item in in_arr:
out_arr.append( product // item )``````

#### Challenge 2: Spiral Matrix

You are given `m x n` matrix of positive integers.

Write a script to print spiral matrix as list.

If you want to think like a robot traversing enemy area, you have to become a robot.

I liked this exercise as there will be certainly similar in the coming Advent Of Code!

I decided to be in the position of a robot crawling the array, going in a direction as far as I can and then change the direction at the end. At the same time keep track of the fields I have seen.

From the code:

1. Initialize the max dimensions, current position, seen cells and the return array.

Perl:

``````my \$x_max = scalar @\$in_arr;
my \$y_max = scalar @{\$in_arr->};

my @pos = (0, 0);
my \$direction = ">";

my %seen_cells;
my @out_arr;``````

Python:

``````x_max = len(in_arr)
y_max = len(in_arr)

pos = [0,0]
direction = ">"

seen_cells = {}
out_arr = []``````
1. Look indefinitely when there are still some fields we have not seen - if so, push the field to the return array and remember we have seen it. If everything has been seen, return the array.

Perl:

``````while (1) {

return \@out_arr if scalar @out_arr == \$x_max * \$y_max;

push @out_arr, \$in_arr->[\$pos][\$pos] unless \$seen_cells{\$pos}{\$pos};
\$seen_cells{\$pos}{\$pos} = 1;``````

Python:

``````while 1:

if len(out_arr) == x_max * y_max:
return out_arr

if seen_cells.get((pos, pos), 0 ) == 0:
out_arr.append(in_arr[pos][pos])

seen_cells[(pos, pos)] = 1``````
1. Check if we can continue in the same direction, otherwise change the direction.

Perl - example for going to the right “>”:

``````# can move in the direction we are walking?
if (\$direction eq ">") {
if ((\$pos + 1 < \$x_max) and not (\$seen_cells{\$pos}{\$pos+1})) {
\$pos++;
} else {
\$direction = "v";
}
}``````

Python:

``````if direction == ">":
if (pos + 1 < x_max) and not (seen_cells.get( (pos, pos+1), 0) ):
pos += 1
else:
direction = "v"``````

Test cases were added to both exercises to make sure it passes the requirements.

Complete code in Github!