# Perl Weekly Challenge 163: the infinite loop

It is sad that, after more than two years of me doing Raku, I still don’t have any production code project to work on. Therefore, in order to keep my coding and Raku-ing (is that a term?) knowdledge, I try to solve every Perl Weekly Challenge tasks.In the following, the assigned tasks for Challenge 163.

and for the sake of some Perl 5, let’s do some stuff also in PostgreSQL Pl/Perl:

Last, the solutions in PostgreSQL PL/PgSQL:

## PWC 163 - Task 1

This task was about doing an integer sum of bitwise ands within an array of numbers. It was not complicated, but it was requiring a full coverage of the index, that means a last step of using the very first and very last elements was required, as well as some conversions from and to integers:```
sub MAIN( *@n where { @n.grep( * ~~ Int ).elems == @n.elems } ) {
my $sum = 0;
$sum += ( @n[ $_ - 1 ].base( 2 ) +& @n[ $_ ].base( 2 ) ).Str.parse-base( 2 ) for 1 ..^ @n.elems;
$sum += ( @n[ 0 ].base( 2 ) +& @n[ * - 1 ].base( 2 ) ).Str.parse-base( 2 );
$sum.say;
}
```

## PWC 163 - Task 2

This task was starting from an array of integers, that have to be progressively reduced by creating a new array with a sum of elements between the previous array and the previous element of the current array.```
sub MAIN( *@n where { @n.grep( * ~~ Int ).elems == @n.elems } ) {
my @matrix;
@matrix.push: [ @n ];
while ( @matrix[ * - 1 ].elems > 2 ) {
my @row;
@row.push: @matrix[ * - 1 ][ 1 ] ;
for 2 ..^ @matrix[ * - 1 ].elems {
@row.push: @matrix[ * - 1 ][ $_ ] + @row[ * - 1 ];
}
@matrix.push: [ @row ];
}
@matrix.push: [ @matrix[ * - 1 ][ * - 1 ] ];
say @matrix[ * - 1 ][ 0 ];
}
```

At every step, a new

`@row`

array of the `@matrix`

is built, and every element of the current `@row`

is made by the second element of the previous row in the matrix, then the sum of the same column element of the current row with the previous element of the current row.
Once the matrix has reached a single element row, the job is done.
## PWC 163 - Task 1 in PostgreSQL PL/Perl

A quite simple translation of the Raku implementation:```
CREATE OR REPLACE FUNCTION
pwc163.task1_plperl( int[] )
RETURNS int
AS $CODE$
my ( $n ) = @_;
my $sum = 0;
for my $index ( 1 .. scalar( @$n ) - 1 ) {
my ( $a, $b ) = ( sprintf( '%03b', $n->[ $index - 1 ] ), sprintf( '%03b', $n->[ $index ] ) );
my $result = $a & $b;
elog( DEBUG, "Nums $n->[ $index - 1 ] and $n->[ $index ] => $a and $b => $result" );
$sum += oct( '0b'. $result );
}
my ( $a, $b ) = ( sprintf( '%03b', $n->[ 0 ] ), sprintf( '%03b', $n->[ -1 ] ) );
my $result = $a & $b;
$sum += oct( '0b'. $result );
return $sum;
$CODE$
LANGUAGE plperl;
```

Note that I use

`sprintf`

and `oct`

as ways to implement Raku `base`

and `parse-base`

methods. Despite this, the alghoritm is the same.
## PWC 163 - Task 2 in PostgreSQL Pl/Perl

Same Raku implementation, but with a trick that made me run into*an infinite loop*:

```
CREATE OR REPLACE FUNCTION
pwc163.task2_plperl( int[] )
RETURNS int
AS $CODE$
my ( $n ) = @_;
my @matrix;
push @matrix, [ @$n ];
while ( scalar( @{ $matrix[ -1 ] } ) > 2 ) {
my @row;
push @row, $matrix[ -1 ][ 1 ];
for my $index ( 2 .. scalar( @{ $matrix[ -1 ] } ) - 1 ) {
push @row, $matrix[ -1 ][ $index ] + $row[ -1 ];
}
elog( DEBUG, "Current row: " . join( ',', @row ) );
push @matrix, [ @row ];
}
return $matrix[ -1 ][ -1 ];
$CODE$
LANGUAGE plperl;
```

At first, I wrongly forgot that in Pl/Perl

**arrays are not really Perl arrays**: they are an

*iterable object*that smells like a Perl array, but needs to be derefenced pretty much any time. So when I looped up to

`scalar $matrix[ -1 ]`

I was issuing an infinite loop because I needed to deference the object asn an array!
## PWC 163 - Task 1 in PostgreSQL Pl/PgSQL

Quite simple, since it is possible to cast a number to`bit`

and then to `int`

again:
```
CREATE OR REPLACE FUNCTION
pwc163.task1_plpgsql( n int[] )
RETURNS int
AS $CODE$
DECLARE
summy int := 0;
index int;
BEGIN
FOR index IN 2 .. array_length( n, 1 ) LOOP
summy := summy
+ ( n[ index - 1 ]::bit(8)
&
n[ index ]::bit( 8 ) )::int;
END LOOP;
summy := summy
+ ( n[ 1 ]::bit(8)
&
n[ array_length( n, 1 ) ]::bit( 8 ) )::int;
RETURN summy;
END
$CODE$
LANGUAGE plpgsql;
```

## PWC 163 - Task 2 in PostgreSQL Pl/PgSQL

This time I took a slightly different approach than those in Raku and PL/Perl: I split the alghoritm in two steps. The first one was a function able to reduce an incoming array into the one with its sums, essentially producing from one row the next one. The second function was a simple loop over the previous one until the array got a single dimension.**Take care that in SQL arrays start from**

`1`

!```
CREATE OR REPLACE FUNCTION
pwc163.task2_reduce( n int[] )
RETURNS int[]
AS $CODE$
DECLARE
summy int;
index int;
res int[];
BEGIN
FOR index IN 2 .. array_length( n, 1 ) LOOP
IF index = 2 THEN
res := array_append( res, n[ index ] );
ELSE
res := array_append( res, n[ index ] + res[ array_length( res, 1 ) ] );
END IF;
END LOOP;
RETURN res;
END
$CODE$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION
pwc163.task2_plpgsql( n int[] )
RETURNS int
AS $CODE$
DECLARE
BEGIN
WHILE array_length( n, 1 ) > 1 LOOP
n := pwc163.task2_reduce( n );
END LOOP;
RETURN n[ 1 ];
END
$CODE$
LANGUAGE plpgsql;
```