Perl Weekly Challenge 353: waiting for Santa…

This post presents my solutions to the Perl Weekly Challenge 353.
I keep doing the Perl Weekly Challenge in order to mantain my coding skills in good shape, as well as in order to learn new things, with particular regard to Raku, a language that I love.
This week, I solved the following tasks:
The PL/Perl implementations are very similar to a pure Perl implementation, even if the PostgreSQL environment could involve some more constraints. Similarly, the PL/PgSQL implementations help me keeping my PostgreSQL programming skills in good shape.

Raku Implementations

PWC 353 - Task 1 - Raku Implementation

The first task was about finding the sentence, given a list in input, with the max number of words. Easy enough to do in a single line!

sub MAIN( *@sentences ) {
    @sentences.map( *.split( /\s+/ ).elems ).max.say;
}



Split every sentence into words, map to the number of words, extract the max value and print it.

PWC 353 - Task 2 - Raku Implementation

The second task was about correlating three arrays to evaluate to true or felase depending on the value of every entry.

sub MAIN(  :@codes,  :@names,  :@status ) {

    my @valid;

    for 0 ..^ @codes.elems  {
		@valid[ $_ ] = False and next unless ( @codes[ $_ ] );
		@valid[ $_ ] = False and next unless ( @codes[ $_ ] ~~ / ^ <[a..zA..Z0..9_]>+ $ / );
		@valid[ $_ ] = False and next unless ( @names[ $_ ] ~~ / electronics|grocery|pharmacy|restaurant / );
		@valid[ $_ ] = False and next unless ( @status[ $_ ].so );
		@valid[ $_ ] = True;
    }

    @valid.say;

}



PL/Perl Implementations

The same as in Raku, only verbose.

PWC 353 - Task 1 - PL/Perl Implementation



CREATE OR REPLACE FUNCTION
pwc353.task1_plperl( text[] )
RETURNS int
AS $CODE$

   my ( $sentences ) = @_;

   my @w = $sentences->@*;
   return ( sort { $b <=> $a }
	    map { scalar split /\s+/, $_   } $sentences->@* )[ 0 ];

$CODE$
LANGUAGE plperl;



I use the trick of sorting the array and get the first element in order to get the max value.

PWC 353 - Task 2 - PL/Perl Implementation

Similar to the Raku approach.

CREATE OR REPLACE FUNCTION
pwc353.task2_plperl( text[], text[], text[] )
RETURNS SETOF text
AS $CODE$

   my ( $codes, $names, $status ) = @_;

   for ( 0 .. $codes->@* - 1 ) {
       my $valid = 1;

       $valid = 0 unless ( $codes->@[ $_ ] =~ / ^ [a-zA-Z0-9_]+ $ /x );
       $valid = 0 unless ( $status->@[ $_ ] =~ /true/i );
       $valid = 0 unless ( $names->@[ $_ ] =~ /electronics|grocery|pharmacy|restaurant/i );
       return_next( $valid ? 'true' : 'false' );
   }

   return undef;

$CODE$
LANGUAGE plperl;



PostgreSQL Implementations

PWC 353 - Task 1 - PL/PgSQL Implementation

A single query does suffice!

CREATE OR REPLACE FUNCTION
pwc353.task1_plpgsql( s text[] )
RETURNS int
AS $CODE$
   SELECT max( regexp_count( x, '\w+' ) )
   FROM   unnest( s ) x;

$CODE$
LANGUAGE sql;



PWC 353 - Task 2 - PL/PgSQL Implementation

Here I cheated, and use PL/Perl to do the trick.

CREATE OR REPLACE FUNCTION
pwc353.task2_plpgsql( c text[], n text[], s text[] )
RETURNS SETOF text
AS $CODE$
   SELECT pwc353.task2_plperl( c, n, s );

$CODE$
LANGUAGE sql;



Java Implementations

PWC 353 - Task 1 - PostgreSQL PL/Java Implementation

Quite simple with an iteration.

    public static final int task1_pljava( String[] sentences ) throws SQLException {
		logger.log( Level.INFO, "Entering pwc353.task1_pljava" );

		int max = 0;
		for ( String s : sentences ) {
		    int current = s.split( "\\s+" ).length;
		    if ( current > max )
				max = current;
		}

		return max;
    }


PWC 353 - Task 2 - PostgreSQL PL/Java Implementation

Simple enough to evaluate in a loop.

    public static final Boolean[] task2_pljava( String codes[],
						String names[],
						String status[] )
	throws SQLException {
		logger.log( Level.INFO, "Entering pwc353.task2_pljava" );

		Boolean result[] = new Boolean[ codes.length ];

		Pattern regex = Pattern.compile( "^[a-z0-9_]+$",
						 Pattern.CASE_INSENSITIVE );


		for ( int i = 0; i < codes.length; i++ ) {
		    	Matcher engine = regex.matcher( codes[ i ] );

			if ( engine.find()
			     && ( names[ i ].equalsIgnoreCase( "electronics" )
				  || names[ i ].equalsIgnoreCase( "grocery" )
				  || names[ i ].equalsIgnoreCase( "pharmacy" )
				  || names[ i ].equalsIgnoreCase( "restaurant" ) )
			     && status[ i ].equalsIgnoreCase( "true" ) )
			    result[ i ] = true;
			else
			    result[ i ] = false;
		}

		return result;
    }


Python Implementations

PWC 353 - Task 1 - Python Implementation

A single line suffice.

import sys
import re

# task implementation
# the return value will be printed
def task_1( args ):
    regex = re.compile( r'\s+' )
    return max( list( map( lambda x: len( regex.split( x ) ), args ) ) )



# invoke the main without the command itself
if __name__ == '__main__':
    print( task_1( sys.argv[ 1: ] ) )



PWC 353 - Task 2 - Python Implementation

Same PL/Java implementation.

import sys
import re

# task implementation
# the return value will be printed
def task_2( args ):
    result  = []
    regex   = re.compile( r'\s+' )
    codes   = list( regex.split( args[0] ) )
    names   = list( regex.split( args[1] ) )
    status  = list( regex.split( args[2] ) )


    r1 = re.compile( r'^[a-zA-Z0-9_]+$' )
    r2 = re.compile( r'^electronics|grocery|pharmacy|restaurant$' )

    for i in range( 0, len( codes ) ):
        if r1.match( codes[ i ] ) and r2.match( names[ i ] ) and status[ i ] == "true":
            result.append( "true" )
        else:
            result.append( "false" )

    return result


# invoke the main without the command itself
if __name__ == '__main__':
    print( task_2( sys.argv[ 1: ] ) )



The article Perl Weekly Challenge 353: waiting for Santa... has been posted by Luca Ferrari on December 24, 2025