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