Perl Weekly Challenge 333: streaming numbers

This post presents my solutions to the Perl Weekly Challenge 333.
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 333 - Task 1 - Raku Implementation

The first task was, given an array of coordinates (two dimensions) to return if the coordinates are all on the same line.

sub MAIN( *@coordinates
	  where { @coordinates.grep( * ~~ Int ).elems == @coordinates.elems && @coordinates.elems %% 2  } ) {

    my @coords;
    for @coordinates -> $x, $y {
		@coords.push: { x => $x, y => $y };
    }

    my $first  = @coords[ 0 ];
    my $second = @coords[ 1 ];

    for 2 ..^ @coords.elems {
	my $current = @coords[ $_ ];
		'False'.say and exit if ( ( $current<x> - $first<x> ) * ( $first<y> - $second<y> )
				  != ( $current<y> - $first<y> ) * ( $first<x> - $second<x> ) );
    }

    'True'.say;
}



The idea is to create an array of coordinates with a pair of x and y, just for making it easier to access the data. Then I iterate over all the points to see if every point is within the same line of the first and second points, and fail at the first point that is not.

PWC 333 - Task 2 - Raku Implementation

Given a list of numbers, duplicate every zero trimming the array to its length.

sub MAIN( *@nums where { @nums.elems == @nums.grep( * ~~ Int ).elems } ) {
    my @result;

    for @nums {
		@result.push: $_;
		@result.push: $_ if ( $_ == 0 );
    }

    @result[ 0 .. @nums.elems - 1 ].join( ', ' ).say;
}



I simply duplicate every zero, and then trim the array to the original size.

PL/Perl Implementations

PWC 333 - Task 1 - PL/Perl Implementation

Same implementation as in Raku.

CREATE OR REPLACE FUNCTION
pwc333.task1_plperl( int[] )
RETURNS boolean
AS $CODE$

   my ( $coordinates ) = @_;
   die "Wrong arguments!" if ( $coordinates->@* % 2 != 0 );

   my @coords;
   while ( $coordinates->@* ) {
   	 push @coords, { x => shift( $coordinates->@* ),
	                 y => shift( $coordinates->@* ) };
   }

   my $first  = $coords[ 0 ];
   my $second = $coords[ 1 ];

   for my $i ( 2 .. $#coords ) {
       my $current = $coords[ $i ];
       return 0 if ( ( $current->{ x } - $first->{ x } ) * ( $first->{ y } - $second->{ y } )
                     != ( $current->{ y } - $first->{ y } ) * ( $first->{ x } - $second->{ x } ) );

   }

   return 1;

$CODE$
LANGUAGE plperl;



PWC 333 - Task 2 - PL/Perl Implementation

This time, I keep the limit to output the array.

CREATE OR REPLACE FUNCTION
pwc333.task2_plperl( int[] )
RETURNS SETOF int
AS $CODE$

   my ( $numbers ) = @_;

   my $limit = scalar( $numbers->@* );
   my $index = 0;

   while ( $limit ) {
   	 my $current = $numbers->@[ $index++ ];
	 return_next( $current );
         $limit--;
	 last if ( ! $limit );
	 return_next( $current ) if ( ! $current );
	 $limit-- if ( ! $current );

   }

   return undef;

$CODE$
LANGUAGE plperl;



PostgreSQL Implementations

PWC 333 - Task 1 - PL/PgSQL Implementation

I cheat here and use PL/Perl to return the result.

CREATE OR REPLACE FUNCTION
pwc333.task1_plpgsql( c int[] )
RETURNS boolean
AS $CODE$
   SELECT pwc333.task1_plperl( c );
$CODE$
LANGUAGE sql;



PWC 333 - Task 2 - PL/PgSQL Implementation

Same implementation as in PL/Perl.

CREATE OR REPLACE FUNCTION
pwc333.task2_plpgsql( n int[] )
RETURNS SETOF int
AS $CODE$
DECLARE
	v int;
	l int;
BEGIN

	l := array_length( n, 1 );

	FOREACH v IN ARRAY n LOOP
		IF l = 0 THEN
		   RETURN;
		END IF;


		RETURN NEXT v;
		l := l - 1;

		IF l = 0 THEN
		   RETURN;
		END IF;

		IF v = 0 THEN
		   RETURN NEXT v;
		   l := l - 1;
		END IF;
	END LOOP;

	RETURN;
END
$CODE$
LANGUAGE plpgsql;



Java Implementations

PWC 333 - Task 1 - PostgreSQL PL/Java Implementation

A simple implementation that resembles the PL/Perl one.

    public static final boolean task1_pljava( int coordinates[] ) throws SQLException {
		logger.log( Level.INFO, "Entering pwc333.task1_pljava" );

		List<Map<String, Integer>> coords = new LinkedList<Map<String, Integer>>();

		for ( int i = 0; i < coordinates.length - 1; i++ ) {
		    Map<String, Integer> current = new HashMap<String, Integer>();
		    current.put( "x", coordinates[ i++ ] );
		    current.put( "y", coordinates[ i ] );
		    coords.add( current );
		}

		Map<String, Integer> first  = coords.get( 0 );
		Map<String, Integer> second = coords.get( 1 );

		for ( int i = 2; i < coords.size(); i++ ) {
		    Map<String, Integer> current = coords.get( i );

		    if ( ( current.get( "x" ) - first.get( "x" ) ) * ( first.get( "y" ) - second.get( "y" ) )
			 != ( current.get( "y" ) - first.get( "y" ) ) * ( first.get( "x" ) - second.get( "x" ) ) )
			return false;
		}

		return true;
    }


PWC 333 - Task 2 - PostgreSQL PL/Java Implementation

Similar to the PL/Perl implementation.

    public static final int[] task2_pljava( int[] numbers ) throws SQLException {
		logger.log( Level.INFO, "Entering pwc333.task2_pljava" );

		List<Integer> result = new LinkedList<Integer>();
		int limit = numbers.length;

		for ( int i = 0; i < numbers.length && limit > 0; i++ ) {
		    result.add( numbers[ i ] );
		    limit--;
		    if ( limit == 0 )
				break;

		    if ( numbers[ i ] == 0 ) {
				result.add( numbers[ i ] );
				limit--;
		    }
		}

		int[] tmp = new int[ result.size() ];
		for ( int i = 0; i < tmp.length; i++ )
		    tmp[ i ] = result.get( i );

		return tmp;

    }


Python Implementations

PWC 333 - Task 1 - Python Implementation

Same implementation as in PL/Perl.

import sys

# task implementation
# the return value will be printed
def task_1( args ):
    coords = []
    for i in range( 0, len( args ) - 1 ):
        if i % 2 != 0:
            continue

        x = int( args[ i ] )
        y = int( args[ i + 1 ] )

        current = {}
        current[ 'x' ] = x
        current[ 'y' ] = y

        coords.append( current )

    first  = coords[ 0 ]
    second = coords[ 1 ]


    for i in range( 2, len( coords ) ):
        current = coords[ i ]
        if ( ( current[ 'x' ] - first[ 'x' ] ) * ( first[ 'y' ] - second[ 'y' ] ) ) != ( ( current[ 'y' ] - second[ 'y' ] ) * ( first[ 'x' ] - second[ 'x' ] ) ):
            return False

    return True



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



PWC 333 - Task 2 - Python Implementation

Same implementation as in PL/Perl.

import sys

# task implementation
# the return value will be printed
def task_2( args ):
    result = []
    limit  = len( args )
    index  = 0

    while limit > 0:
        current = int( args[ index ] )
        index   = index + 1
        result.append( current )
        limit = limit - 1
        if limit == 0:
            break

        if current == 0:
            result.append( current )
            limit = limit - 1
            if limit == 0:
                break

    return result

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



The article Perl Weekly Challenge 333: streaming numbers has been posted by Luca Ferrari on August 4, 2025