Perl Weekly Challenge 244: grep and filter everywhere!
This post presents my solutions to the Perl Weekly Challenge 244.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 244 - Task 1 - Raku
- PWC 244 - Task 2 - Raku
- PWC 244 - Task 1 in PostgreSQL PL/Perl
- PWC 244 - Task 2 in PostgreSQL PL/Perl
- PWC 244 - Task 1 in PostgreSQL PL/PgSQL
- PWC 244 - Task 2 in PostgreSQL PL/PgSQL
- PWC 244 - Task 1 in Python
- PWC 244 - Task 2 in Python
Raku Implementations
PWC 244 - Task 1 - Raku Implementation
The first task was about producing an array of integers where each element is the counting of how many integers are greater than the given input valu within an array of integers.sub MAIN( *@nums where { @nums.elems == @nums.grep( * ~~ Int ).elems } ) {
my @result;
@result[ $_ ] = @nums.grep( * > @nums[ $_ ] ).elems for 0 ..^ @nums.elems;
@result.say;
}
PWC 244 - Task 2 - Raku Implementation
The second task was about computing the power of a group of heroes, each one with a given strenght in an array of integers. There was the need to comput all the possible combinations of heroes.sub MAIN( *@nums where { @nums.elems == @nums.grep( * ~~ Int ).elems } ) {
my $power = 0;
for @nums.combinations {
next if ! $_;
$power += $_.min * ( $_.max ** 2 );
}
$power.say;
}
PL/Perl Implementations
PWC 244 - Task 1 - PL/Perl Implementation
Similar to the Raku implementation.CREATE OR REPLACE FUNCTION
pwc244.task1_plperl( int[] )
RETURNS SETOF int
AS $CODE$
my ( $nums ) = @_;
for my $needle ( $nums->@* ) {
return_next( scalar( grep( { $_ > $needle } $nums->@* ) ) );
}
return undef;
$CODE$
LANGUAGE plperl;
PWC 244 - Task 2 - PL/Perl Implementation
I decide to use two libraries,List::Util
and Alghoritm::Combinatorics
to get functions that can help me get all the combinations and the needed min and max values out of an array.
CREATE OR REPLACE FUNCTION
pwc244.task2_plperl( int[] )
RETURNS int
AS $CODE$
use Algorithm::Combinatorics qw/ combinations /;
use List::Util qw/ min max /;
my ( $nums ) = @_;
my $power;
$power = 0;
for my $k ( 1 .. $nums->@* ) {
my $combinations = combinations( \ $nums->@*, $k );
while ( my $iter = $combinations->next ) {
$power += min( $iter->@* ) * ( max( $iter->@* ) ** 2 );
}
}
return $power;
$CODE$
LANGUAGE plperlu;
There is an interesting thing to note here: even if
$nums
is like an array reference, the combinations
method does not accept it as an arrayref, and therefore I needed to transform it into an array and get back the explicit reference.
PostgreSQL Implementations
PWC 244 - Task 1 - PL/PgSQL Implementation
It is easy enough to get the count of the elements greater than the given one, thanks to a single query.CREATE OR REPLACE FUNCTION
pwc244.task1_plpgsql( nums int[] )
RETURNS SETOF int
AS $CODE$
DECLARE
v int;
returning int;
BEGIN
FOREACH v IN ARRAY nums LOOP
SELECT count(*)
INTO returning
FROM unnest( nums ) n
WHERE n > v;
RETURN NEXT returning;
END LOOP;
RETURN;
END
$CODE$
LANGUAGE plpgsql;
PWC 244 - Task 2 - PL/PgSQL Implementation
I cheated here! Since obtaining all the combinations is too much work to be done in SQL, I delegated the PL/Perl to answer the task.CREATE OR REPLACE FUNCTION
pwc244.task2_plpgsql( nums int[] )
RETURNS int
AS $CODE$
SELECT pwc244.task2_plperl( nums );
$CODE$
LANGUAGE sql;
Python Implementations
PWC 244 - Task 1 - Python Implementation
I usefilter
as an alternative to the Perl’s grep
function, then I append the single result into the result
array and output it.
import sys
# task implementation
def main( argv ):
nums = list( map( int, argv ) )
result = []
for current in nums:
result.append( len( list( filter( lambda x: x > current, nums ) ) ) )
print( ", ".join( map( str, result ) ) )
# invoke the main without the command itself
if __name__ == '__main__':
main( sys.argv[ 1: ] )
PWC 244 - Task 2 - Python Implementation
I useitertoolsd.combinations
to get all the possible combinations, even if I need one unit more than the len
of the array.
import sys
from itertools import combinations;
# task implementation
def main( argv ):
nums = list( map( int, argv ) )
power = 0
for size in range( 1, len( nums ) + 1 ):
for current in combinations( nums, size ):
power = power + ( max( current ) ** 2 ) * min( current )
print( power )
# invoke the main without the command itself
if __name__ == '__main__':
main( sys.argv[ 1: ] )