Perl Weekly Challenge 217: Did I misunderstand?
This post presents my solutions to the Perl Weekly Challenge 217.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 217 - Task 1 - Raku
- PWC 217 - Task 2 - Raku
- PWC 217 - Task 1 in PostgreSQL PL/Perl
- PWC 217 - Task 2 in PostgreSQL PL/Perl
- PWC 217 - Task 1 in PostgreSQL PL/PgSQL
- PWC 217 - Task 2 in PostgreSQL PL/PgSQL
Raku Implementations
PWC 217 - Task 1 - Raku Implementation
The first task was about to find the fourth element in a sorted matrix made of integers. As far as I understand from the examples, the matrix is flattened into an array, sorted naturally and then the fourth element is extracted. This made me implement it as an application accepting a flat array.sub MAIN( *@n where { @n.grep( * ~~ Int ).elems == @n.elems } ) {
@n.sort()[ 3 ].say;
}
PWC 217 - Task 2 - Raku Implementation
Given a list of integers, find out their composition that provides the biggest integer as a result.sub MAIN( *@list where { @list.grep( * ~~ Int ).elems == @list.elems } ) {
my $max = 0;
for @list.permutations {
$max = $_.join if ( $_.join.Int > $max );
}
$max.say;
}
The idea is to search thru all the permutations of the input array, trying to see if the array can be
join
ed into a $max
value.
PL/Perl Implementations
PWC 217 - Task 1 - PL/Perl Implementation
If the function accepts the flattened matrix, its implementation is really simple:CREATE OR REPLACE FUNCTION
pwc217.task1_plperl( int[] )
RETURNS int
AS $CODE$
my ( $array ) = @_;
return ( sort( $array->@* ) )[ 3 ];
$CODE$
LANGUAGE plperl;
PWC 217 - Task 2 - PL/Perl Implementation
A all permutations based implementation, where I use theList::Permutor
module and hence the plperlu
untrusted language:
CREATE OR REPLACE FUNCTION
pwc217.task2_plperl( int[] )
RETURNS int
AS $CODE$
use List::Permutor;
my ( $max ) = 0;
my $engine = List::Permutor->new( $_[0]->@* );
while ( my @current = $engine->next ) {
$max = join( '', @current ) if ( join( '', @current ) > $max );
}
return $max;
$CODE$
LANGUAGE plperlu;
PostgreSQL Implementations
PWC 217 - Task 1 - PL/PgSQL Implementation
A single query in SQL:CREATE OR REPLACE FUNCTION
pwc217.task1_plpgsql( a int[] )
RETURNS int
AS $CODE$
SELECT v
FROM unnest( a ) v
ORDER BY 1
LIMIT 1
OFFSET 3;
$CODE$
LANGUAGE sql;
The idea is to
unnest
the incoming array, making it a table, order the result by the values, get a single result at displacement 3.
PWC 217 - Task 2 - PL/PgSQL Implementation
Again, a single query implementation:CREATE OR REPLACE FUNCTION
pwc217.task2_plpgsql( a int[] )
RETURNS int
AS $CODE$
SELECT string_agg( v.vv::text, '' )::int
FROM ( SELECT vv
FROM unnest( a ) vv
ORDER BY ( vv % 10 ) DESC ) v;
$CODE$
LANGUAGE sql;
I
unnest
the array making it a table, and order the result by the remainder of 10
. Then I aggregate the result into a single tring, that is then cast to an integer. This is not a perfect solution, since it assumes you don’t specify numbers greater than 10
.