diff options
| author | Luca Ferrari <fluca1978@gmail.com> | 2025-11-20 10:48:16 +0100 |
|---|---|---|
| committer | Luca Ferrari <fluca1978@gmail.com> | 2025-11-20 14:11:19 +0100 |
| commit | 244472371574d4832deb16a75279e93b4a5a1498 (patch) | |
| tree | baa459e687f55eace42f94fbcfa4cf1afd857a02 | |
| parent | aa283ea4bec57f330a917dba4a1c8b13102c6008 (diff) | |
| download | perlweeklychallenge-club-244472371574d4832deb16a75279e93b4a5a1498.tar.gz perlweeklychallenge-club-244472371574d4832deb16a75279e93b4a5a1498.tar.bz2 perlweeklychallenge-club-244472371574d4832deb16a75279e93b4a5a1498.zip | |
PWC 348
Task 1 Raku done
Task 2 Raku done
Task 1 PL/Perl done
Task 2 PL/Perl done
Task 1 PL/PgSQL done
Task 2 PL/PgSQL done
Task 1 PL/Java done
Task 2 PL/Java done
Task 1 Python done
Task 2 Python done
21 files changed, 443 insertions, 3 deletions
diff --git a/challenge-348/luca-ferrari/blog-1.txt b/challenge-348/luca-ferrari/blog-1.txt new file mode 100644 index 0000000000..5a5d09aa8c --- /dev/null +++ b/challenge-348/luca-ferrari/blog-1.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task1 diff --git a/challenge-348/luca-ferrari/blog-10.txt b/challenge-348/luca-ferrari/blog-10.txt new file mode 100644 index 0000000000..52a7be9f85 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-10.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task2pljava diff --git a/challenge-348/luca-ferrari/blog-2.txt b/challenge-348/luca-ferrari/blog-2.txt new file mode 100644 index 0000000000..314ed9263a --- /dev/null +++ b/challenge-348/luca-ferrari/blog-2.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task2 diff --git a/challenge-348/luca-ferrari/blog-3.txt b/challenge-348/luca-ferrari/blog-3.txt new file mode 100644 index 0000000000..841ebeab44 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-3.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task1plperl diff --git a/challenge-348/luca-ferrari/blog-4.txt b/challenge-348/luca-ferrari/blog-4.txt new file mode 100644 index 0000000000..f1f2e95017 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-4.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task2plperl diff --git a/challenge-348/luca-ferrari/blog-5.txt b/challenge-348/luca-ferrari/blog-5.txt new file mode 100644 index 0000000000..645252a466 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-5.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task1plpgsql diff --git a/challenge-348/luca-ferrari/blog-6.txt b/challenge-348/luca-ferrari/blog-6.txt new file mode 100644 index 0000000000..3e77e2e266 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-6.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task2plpgsql diff --git a/challenge-348/luca-ferrari/blog-7.txt b/challenge-348/luca-ferrari/blog-7.txt new file mode 100644 index 0000000000..89d805e7f7 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-7.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task1python diff --git a/challenge-348/luca-ferrari/blog-8.txt b/challenge-348/luca-ferrari/blog-8.txt new file mode 100644 index 0000000000..382d75fa2e --- /dev/null +++ b/challenge-348/luca-ferrari/blog-8.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task2python diff --git a/challenge-348/luca-ferrari/blog-9.txt b/challenge-348/luca-ferrari/blog-9.txt new file mode 100644 index 0000000000..a17b662d46 --- /dev/null +++ b/challenge-348/luca-ferrari/blog-9.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/20/PerlWeeklyChallenge348.html#task1pljava diff --git a/challenge-348/luca-ferrari/pljava/pom.xml b/challenge-348/luca-ferrari/pljava/pom.xml index 9d238d7670..d1e54ecdf9 100644 --- a/challenge-348/luca-ferrari/pljava/pom.xml +++ b/challenge-348/luca-ferrari/pljava/pom.xml @@ -7,14 +7,14 @@ <groupId>PWC</groupId> <artifactId> - PWC347 + PWC348 </artifactId> <version> 1 </version> - <name>Perl Weekly Challenge 347 with package PWC347</name> - <description>Implementation of the tasks in PL/Java for PWC 347</description> + <name>Perl Weekly Challenge 348 with package PWC348</name> + <description>Implementation of the tasks in PL/Java for PWC 348</description> <properties> <project.build.sourceEncoding>US-ASCII</project.build.sourceEncoding> diff --git a/challenge-348/luca-ferrari/pljava/src/main/java/Task1.java b/challenge-348/luca-ferrari/pljava/src/main/java/Task1.java new file mode 100644 index 0000000000..9440f7a628 --- /dev/null +++ b/challenge-348/luca-ferrari/pljava/src/main/java/Task1.java @@ -0,0 +1,74 @@ + + + +package PWC348; + +/** + * PL/Java implementation for PWC 348 + * Task 1 + * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> + * + * + * To compile on the local machine: + + $ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/ # if not already set + $ mvn clean build + $ scp target/PWC348-1.jar luca@rachel:/tmp + + + * To install into PostgreSQL execute: + + select sqlj.install_jar( 'file:///tmp/PWC348-1.jar', 'PWC348', true ); + select sqlj.set_classpath( 'public', 'PWC348' ); + + select pwc348.task2_pljava(); + + and then to redeploy: + + select sqlj.replace_jar( 'file:///tmp/PWC348-1.jar', 'PWC348', true ); + +*/ + +import org.postgresql.pljava.*; +import org.postgresql.pljava.annotation.Function; +import static org.postgresql.pljava.annotation.Function.Effects.IMMUTABLE; +import static org.postgresql.pljava.annotation.Function.OnNullInput.RETURNS_NULL; + +import java.util.*; +import java.util.stream.*; +import java.sql.SQLException; +import java.util.logging.*; +import java.sql.ResultSet; +import java.sql.Date; + +public class Task1 { + + private final static Logger logger = Logger.getAnonymousLogger(); + + @Function( schema = "pwc348", + onNullInput = RETURNS_NULL, + effects = IMMUTABLE ) + public static boolean task1_pljava( String text ) throws SQLException { + logger.log( Level.INFO, "Entering pwc348.task1_pljava" ); + + if ( text == null || text.isEmpty() || text.length() %2 != 0 ) + return false; + + int left = 0, right = 0, middle = text.length() / 2; + int index = 0; + String vowels = "aeiou"; + for ( String c : text.split( "" ) ) { + index++; + + if ( vowels.indexOf( c ) < 0 ) + continue; + + if ( index <= middle ) + left++; + else + right++; + } + + return left == right; + } +} diff --git a/challenge-348/luca-ferrari/pljava/src/main/java/Task2.java b/challenge-348/luca-ferrari/pljava/src/main/java/Task2.java new file mode 100644 index 0000000000..ffa6ecd5e9 --- /dev/null +++ b/challenge-348/luca-ferrari/pljava/src/main/java/Task2.java @@ -0,0 +1,80 @@ + + + +package PWC348; + +/** + * PL/Java implementation for PWC 348 + * Task 2 + * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> + * + * + * To compile on the local machine: + + $ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/ # if not already set + $ mvn clean build + $ scp target/PWC348-1.jar luca@rachel:/tmp + + + * To install into PostgreSQL execute: + + select sqlj.install_jar( 'file:///tmp/PWC348-1.jar', 'PWC348', true ); + select sqlj.set_classpath( 'public', 'PWC348' ); + + select pwc348.task2_pljava(); + + and then to redeploy: + + select sqlj.replace_jar( 'file:///tmp/PWC348-1.jar', 'PWC348', true ); + +*/ + +import org.postgresql.pljava.*; +import org.postgresql.pljava.annotation.Function; +import static org.postgresql.pljava.annotation.Function.Effects.IMMUTABLE; +import static org.postgresql.pljava.annotation.Function.OnNullInput.RETURNS_NULL; + +import java.util.*; +import java.util.stream.*; +import java.sql.SQLException; +import java.util.logging.*; +import java.sql.ResultSet; +import java.sql.Date; + +public class Task2 { + + private final static Logger logger = Logger.getAnonymousLogger(); + + @Function( schema = "pwc348", + onNullInput = RETURNS_NULL, + effects = IMMUTABLE ) + public static final int task2_pljava( String source, String target ) throws SQLException { + logger.log( Level.INFO, "Entering pwc348.task2_pljava" ); + + int src_mins = 0; + int dst_mins = 0; + int[] multipliers = { 60, 1 }; + List<Integer> operations = new LinkedList<Integer>(); + + int index = 0; + for ( String part : source.split( ":" ) ) + src_mins += Integer.parseInt( part ) * multipliers[ index++ ]; + + + index = 0; + for ( String part : target.split( ":" ) ) + dst_mins += Integer.parseInt( part ) * multipliers[ index++ ]; + + + int ops[] = { 60, 15, 10, 5, 1 }; + for ( int op : ops ) + while ( dst_mins - src_mins >= op ) { + src_mins += op; + operations.add( op ); + } + + + return operations.size(); + + } +} diff --git a/challenge-348/luca-ferrari/plperl/ch-1.plperl b/challenge-348/luca-ferrari/plperl/ch-1.plperl new file mode 100644 index 0000000000..b276c70cb1 --- /dev/null +++ b/challenge-348/luca-ferrari/plperl/ch-1.plperl @@ -0,0 +1,25 @@ +-- +-- Perl Weekly Challenge 348 +-- Task 1 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +-- + +CREATE SCHEMA IF NOT EXISTS pwc348; + +CREATE OR REPLACE FUNCTION +pwc348.task1_plperl( text ) +RETURNS boolean +AS $CODE$ + + my ( $text ) = @_; + + return 0 unless ( length( $text ) % 2 == 0 ); + + my @chars = split //, $text; + my ( @left, @right ) = ( @chars[ 0 .. $#chars / 2 - 1 ], + @chars[ $#chars / 2 .. $#chars ] ); + + return scalar( grep( { $_ =~ / [aeiou] / } @left ) ) == scalar( grep( { $_ =~ / [aeiou] / } @right ) ); + +$CODE$ +LANGUAGE plperl; diff --git a/challenge-348/luca-ferrari/plperl/ch-2.plperl b/challenge-348/luca-ferrari/plperl/ch-2.plperl new file mode 100644 index 0000000000..b6a87150d7 --- /dev/null +++ b/challenge-348/luca-ferrari/plperl/ch-2.plperl @@ -0,0 +1,34 @@ +-- +-- Perl Weekly Challenge 348 +-- Task 2 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +-- + +CREATE SCHEMA IF NOT EXISTS pwc348; + +CREATE OR REPLACE FUNCTION +pwc348.task2_plperl( text, text ) +RETURNS int +AS $CODE$ + + my ( $source, $target ) = @_; + + my @elems = split /[:]/, $source; + my $src_mins = $elems[ 0 ] * 60 + $elems[ 1 ]; + + @elems = split /[:]/, $target; + my $dst_mins = $elems[ 0 ] * 60 + $elems[ 1 ]; + + my @operations; + for my $current ( 60, 15, 10, 5, 1 ) { + while ( $dst_mins - $src_mins >= $current ) { + push @operations, $current; + $src_mins += $current; + } + } + + return scalar( @operations ); + + +$CODE$ +LANGUAGE plperl; diff --git a/challenge-348/luca-ferrari/plpgsql/ch-1.sql b/challenge-348/luca-ferrari/plpgsql/ch-1.sql new file mode 100644 index 0000000000..c293c3fafe --- /dev/null +++ b/challenge-348/luca-ferrari/plpgsql/ch-1.sql @@ -0,0 +1,40 @@ +-- +-- Perl Weekly Challenge 348 +-- Task 1 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +-- + +CREATE SCHEMA IF NOT EXISTS pwc348; + +CREATE OR REPLACE FUNCTION +pwc348.task1_plpgsql( s text ) +RETURNS boolean +AS $CODE$ +DECLARE + lc int; + rc int; + sz int; +BEGIN + if mod( length( s ), 2 ) <> 0 then + return false; + else + sz := length( s ) / 2; + end if; + + SELECT count( t.* ) + INTO lc + FROM ( SELECT regexp_matches( lower( left( s, sz ) ), '[aeiou]' ) ) t; + + SELECT count( t.* ) + INTO rc + FROM ( SELECT regexp_matches( lower( right( s, sz ) ), '[aeiou]' ) ) t; + + + IF lc = rc THEN + RETURN true; + ELSE + RETURN false; + END IF; +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-348/luca-ferrari/plpgsql/ch-2.sql b/challenge-348/luca-ferrari/plpgsql/ch-2.sql new file mode 100644 index 0000000000..8d0573787b --- /dev/null +++ b/challenge-348/luca-ferrari/plpgsql/ch-2.sql @@ -0,0 +1,46 @@ +-- +-- Perl Weekly Challenge 348 +-- Task 2 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +-- + +CREATE SCHEMA IF NOT EXISTS pwc348; + +CREATE OR REPLACE FUNCTION +pwc348.task2_plpgsql( s text, t text ) +RETURNS int +AS $CODE$ +DECLARE + operations int := 0; + src_mins int := 0; + dst_mins int := 0; + multiplier int := 0; + v text; + x int; +BEGIN + + multiplier := 60; + FOR v IN SELECT * FROM regexp_split_to_table( s, '[:]' ) LOOP + src_mins := src_mins + v::int * multiplier; + multiplier := 1; + END LOOP; + + multiplier := 60; + FOR v IN SELECT * FROM regexp_split_to_table( t, '[:]' ) LOOP + dst_mins := dst_mins + v::int * multiplier; + multiplier := 1; + END LOOP; + + FOREACH x IN ARRAY array[ 60, 15, 10, 5, 1 ]::int[] LOOP + WHILE dst_mins - src_mins >= x LOOP + src_mins := src_mins + x; + operations := operations + 1; + END LOOP; + END LOOP; + + RETURN operations; + + +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-348/luca-ferrari/python/ch-1.py b/challenge-348/luca-ferrari/python/ch-1.py new file mode 100644 index 0000000000..d864fd413a --- /dev/null +++ b/challenge-348/luca-ferrari/python/ch-1.py @@ -0,0 +1,36 @@ +#!python + +# +# Perl Weekly Challenge 348 +# Task 1 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +# + +import sys + +# task implementation +# the return value will be printed +def task_1( args ): + lc = 0 + rc = 0 + middle = len( args[ 0 ] ) / 2 + index = 0 + vowels = [ 'a', 'e', 'i', 'o', 'u' ] + + for c in args[ 0 ].lower() : + index += 1 + + if c in vowels : + if index <= middle : + lc += 1 + else : + rc += 1 + + return lc == rc + + + +# invoke the main without the command itself +if __name__ == '__main__': + print( task_1( sys.argv[ 1: ] ) ) diff --git a/challenge-348/luca-ferrari/python/ch-2.py b/challenge-348/luca-ferrari/python/ch-2.py new file mode 100644 index 0000000000..1a5ffc63b0 --- /dev/null +++ b/challenge-348/luca-ferrari/python/ch-2.py @@ -0,0 +1,44 @@ +#!python + +# +# Perl Weekly Challenge 348 +# Task 2 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +# + +import sys + +# task implementation +# the return value will be printed +def task_2( args ): + source = args[ 0 ] + target = args[ 1 ] + multi = [ 60, 1 ] + index = 0 + + src_mins = 0 + dst_mins = 0 + + + for p in source.split( ':' ) : + src_mins += int( p ) * multi[ index ] + index += 1 + + index = 0 + for p in target.split( ':' ) : + dst_mins += int( p ) * multi[ index ] + index += 1 + + op_list = [] + operations = [ 60, 15, 10, 5, 1 ] + for op in operations : + while dst_mins - src_mins >= op : + src_mins += op + op_list.append( op ) + + return len( op_list ) + +# invoke the main without the command itself +if __name__ == '__main__': + print( task_2( sys.argv[ 1: ] ) ) diff --git a/challenge-348/luca-ferrari/raku/ch-1.raku b/challenge-348/luca-ferrari/raku/ch-1.raku new file mode 100644 index 0000000000..2d58a16bbb --- /dev/null +++ b/challenge-348/luca-ferrari/raku/ch-1.raku @@ -0,0 +1,18 @@ +#!raku + +# +# Perl Weekly Challenge 348 +# Task 1 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +# + +sub MAIN( Str $string ) { + # if the string has an even length, nothing to do + 'False'.say and exit( 1 ) if ( $string.chars !%% 2 ); + 'False'.say and exit( 2 ) unless ( $string.comb[ 0 ..^ $string.chars / 2 ].fc.grep( * ~~ /<[aeiou]>/ ).elems == + $string.comb[ $string.chars / 2 .. * ].fc.grep( * ~~ /<[aeiou]>/ ).elems ); + + + 'True'.say; +} diff --git a/challenge-348/luca-ferrari/raku/ch-2.raku b/challenge-348/luca-ferrari/raku/ch-2.raku new file mode 100644 index 0000000000..8959ef64ef --- /dev/null +++ b/challenge-348/luca-ferrari/raku/ch-2.raku @@ -0,0 +1,33 @@ +#!raku + +# +# Perl Weekly Challenge 348 +# Task 2 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-348> +# + +sub MAIN( Str $source, Str $target where { $source ~~ / ^ \d ** 2 <[:]> \d ** 2 $ / && $target ~~ / ^ \d ** 2 <[:]> \d ** 2 $ / } ) { + my %begin = hour => $source.split( ':' )[ 0 ], + mins => $source.split( ':' )[ 1 ]; + + my %end = hour => $target.split( ':' )[ 0 ], + mins => $target.split( ':' )[ 1 ]; + + + %begin<mins> = %begin<mins> + %begin<hour> * 60; + %end<mins> = %end<mins> + %end<hour> * 60; + + my @operations; + + for ( 60, 15, 10, 5, 1 ) -> $current { + while ( %end<mins> - %begin<mins> >= $current ) { + %begin<mins> += $current; + @operations.push: $current; + + } + } + + @operations.elems.say; + +} |
