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:
- PWC 353 - Task 1 - Raku
- PWC 353 - Task 2 - Raku
- PWC 353 - Task 1 in PostgreSQL PL/Perl
- PWC 353 - Task 2 in PostgreSQL PL/Perl
- PWC 353 - Task 1 in PostgreSQL PL/PgSQL
- PWC 353 - Task 2 in PostgreSQL PL/PgSQL
- PWC 353 - Task 1 in PL/Java
- PWC 353 - Task 2 in PL/Java
- PWC 353 - Task 1 in Python
- PWC 353 - Task 2 in Python
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 totrue 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: ] ) )