Perl Weekly Challenge 145: the last challenge of the year!

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 145.


And this week, as for the previous PWC, I had time to quickly implement the tasks also on PostgreSQL plpgsql language:

PWC 145 - Task 1

The first task, named dot product was really simple to solve in Raku: it was the calculation of the sum of a product across euqlly sized arrays.

sub MAIN(  *@n where { @n.elems %% 2 && @n.grep( * ~~ Int ).elems == @n.elems } ) {
    ( [+] ( @n[ 0 .. @n.elems / 2 - 1 ] Z* @n[ @n.elems / 2 .. * - 1 ] ) ).say;
}


The idea is simple: all the program input is split into two arrays of equal size, that are multiplied using the zip operator Z* that performs the multiplication of elements of the same position. The resulting array is reduced by [+] that performs the sum operation. The final result is printed out.

PWC 145 - Task 2

The second task, as very often it happens, was harder to solve: a palindromic tree that is the construction of a set of nodes that leave a palindrome string within a given input.

sub MAIN( Str $s = 'redivider' ) {

    my @roots;
    my @chars = $s.comb;

    for 0 ..^ @chars.elems -> $current {
        my $current-root = @chars[ $current ];


        for $current + 1 ..^ @chars.elems -> $other {
            next if @chars[ $other ] !~~ $current-root;

            my $string = @chars[ $current .. $other ].join;

            if ( $string ~~ $string.flip ) {
                @roots.push: [ $current-root, $string ];
                last;
            }
        }

        @roots.push: [ $current-root, '' ] if ! @roots.grep({  $_[ 0 ] ~~ $current-root } );
    }

    "$_[0] = $_[1]".say for @roots;
}




I used a nested loop: in the outer loop I take a $current-root possible solution, and then try to find out the first palindrome string I can find (with the inner loop). Once I found the palindrome string, I then push an array with the root letter and the resulting string. Last, I do print all the solutions I found.

PWC 145 - Task 1 in PostgreSQL

The first task could be achived with a FOR loop over the array size (the array are supposed to be equally sized) and cumulatively compute the sum of the products.

CREATE OR REPLACE FUNCTION
f_dot_product( a int[], b int[] )
RETURNS int
AS
$CODE$
DECLARE
        i int;
        total int := 0;
BEGIN
        FOR i IN 1 .. array_length( a, 1 ) LOOP
            total := total + a[ i ] * b[ i ];
        END LOOP;

        RETURN total;
END
$CODE$
LANGUAGE plpgsql;




PWC 145 - Task 2 in PostgreSQL

This is a clear re-implementation of what I did in Raku:

CREATE OR REPLACE FUNCTION
f_eertree( s text )
RETURNS TABLE( current_root char, string text )
AS $CODE$
DECLARE
        current int;
        other   int;
        other_root   char;
BEGIN

        FOR current IN 1 .. length( s ) LOOP
           current_root := substring( s FROM current FOR  1 );

           FOR other IN current + 1 .. length( s ) LOOP
               other_root := substring( s FROM other FOR 1 );
               IF other_root <> current_root THEN
                  CONTINUE;
               END IF;

               string := substring( s, current, other - current + 1 );

               IF string = reverse( string ) THEN
                  RETURN NEXT;
               END IF;

           END LOOP;
        END LOOP;

        RETURN;

END
$CODE$
LANGUAGE plpgsql;


A particular aspect of this function is that it returns a TABLE, that is something that has columns and rows. Columns declared in the output table become lexically visible variables, so that it does suffice to assign to them a value and issue a RETURN NEXT to append all of them to the result set.

The article Perl Weekly Challenge 145: the last challenge of the year! has been posted by Luca Ferrari on December 29, 2021