aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Ferrari <fluca1978@gmail.com>2024-04-08 14:13:18 +0200
committerLuca Ferrari <fluca1978@gmail.com>2024-04-08 16:58:40 +0200
commit2126fcd1ffcf87c9eb31ac28b50ff5fa9315bf0b (patch)
tree9d045266c0b9d398181f6b948877d9d52170a626
parentf14e99c374e42f272a7e43324e5ac195996c9a54 (diff)
downloadperlweeklychallenge-club-2126fcd1ffcf87c9eb31ac28b50ff5fa9315bf0b.tar.gz
perlweeklychallenge-club-2126fcd1ffcf87c9eb31ac28b50ff5fa9315bf0b.tar.bz2
perlweeklychallenge-club-2126fcd1ffcf87c9eb31ac28b50ff5fa9315bf0b.zip
PWC 264
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
-rw-r--r--challenge-264/luca-ferrari/blog-1.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-10.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-2.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-3.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-4.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-5.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-6.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-7.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-8.txt1
-rw-r--r--challenge-264/luca-ferrari/blog-9.txt1
-rw-r--r--challenge-264/luca-ferrari/pljava/pom.xml6
-rw-r--r--challenge-264/luca-ferrari/pljava/src/main/java/Task1.java72
-rw-r--r--challenge-264/luca-ferrari/pljava/src/main/java/Task2.java79
-rw-r--r--challenge-264/luca-ferrari/plperl/ch-1.plperl28
-rw-r--r--challenge-264/luca-ferrari/plperl/ch-2.plperl48
-rw-r--r--challenge-264/luca-ferrari/plpgsql/ch-1.sql42
-rw-r--r--challenge-264/luca-ferrari/plpgsql/ch-2.sql46
-rw-r--r--challenge-264/luca-ferrari/python/ch-1.py38
-rw-r--r--challenge-264/luca-ferrari/python/ch-2.py46
-rw-r--r--challenge-264/luca-ferrari/raku/ch-1.raku19
-rw-r--r--challenge-264/luca-ferrari/raku/ch-2.raku31
21 files changed, 462 insertions, 3 deletions
diff --git a/challenge-264/luca-ferrari/blog-1.txt b/challenge-264/luca-ferrari/blog-1.txt
new file mode 100644
index 0000000000..049120fb65
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-1.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task1
diff --git a/challenge-264/luca-ferrari/blog-10.txt b/challenge-264/luca-ferrari/blog-10.txt
new file mode 100644
index 0000000000..de2fcbb669
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-10.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/[= date -%]/PerlWeeklyChallenge264.html#task2pljava
diff --git a/challenge-264/luca-ferrari/blog-2.txt b/challenge-264/luca-ferrari/blog-2.txt
new file mode 100644
index 0000000000..f0e7276d80
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-2.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task2
diff --git a/challenge-264/luca-ferrari/blog-3.txt b/challenge-264/luca-ferrari/blog-3.txt
new file mode 100644
index 0000000000..fd1f01fa35
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-3.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task1plperl
diff --git a/challenge-264/luca-ferrari/blog-4.txt b/challenge-264/luca-ferrari/blog-4.txt
new file mode 100644
index 0000000000..413cee23bf
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-4.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task2plperl
diff --git a/challenge-264/luca-ferrari/blog-5.txt b/challenge-264/luca-ferrari/blog-5.txt
new file mode 100644
index 0000000000..24cd02fb78
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-5.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task1plpgsql
diff --git a/challenge-264/luca-ferrari/blog-6.txt b/challenge-264/luca-ferrari/blog-6.txt
new file mode 100644
index 0000000000..5887a4b64d
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-6.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task2plpgsql
diff --git a/challenge-264/luca-ferrari/blog-7.txt b/challenge-264/luca-ferrari/blog-7.txt
new file mode 100644
index 0000000000..8e1a8446e1
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-7.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task1python
diff --git a/challenge-264/luca-ferrari/blog-8.txt b/challenge-264/luca-ferrari/blog-8.txt
new file mode 100644
index 0000000000..8353990d6d
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-8.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task2python
diff --git a/challenge-264/luca-ferrari/blog-9.txt b/challenge-264/luca-ferrari/blog-9.txt
new file mode 100644
index 0000000000..ac2f814a28
--- /dev/null
+++ b/challenge-264/luca-ferrari/blog-9.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2024/04/08/PerlWeeklyChallenge264.html#task1pljava
diff --git a/challenge-264/luca-ferrari/pljava/pom.xml b/challenge-264/luca-ferrari/pljava/pom.xml
index 23b9d42d1a..f0407a6920 100644
--- a/challenge-264/luca-ferrari/pljava/pom.xml
+++ b/challenge-264/luca-ferrari/pljava/pom.xml
@@ -7,14 +7,14 @@
<groupId>PWC</groupId>
<artifactId>
- PWC263
+ PWC264
</artifactId>
<version>
1
</version>
- <name>Perl Weekly Challenge 263 with package PWC263</name>
- <description>Implementation of the tasks in PL/Java for PWC 263</description>
+ <name>Perl Weekly Challenge 264 with package PWC264</name>
+ <description>Implementation of the tasks in PL/Java for PWC 264</description>
<properties>
<project.build.sourceEncoding>US-ASCII</project.build.sourceEncoding>
diff --git a/challenge-264/luca-ferrari/pljava/src/main/java/Task1.java b/challenge-264/luca-ferrari/pljava/src/main/java/Task1.java
new file mode 100644
index 0000000000..18f95cc42a
--- /dev/null
+++ b/challenge-264/luca-ferrari/pljava/src/main/java/Task1.java
@@ -0,0 +1,72 @@
+
+
+
+package PWC264;
+
+/**
+ * PL/Java implementation for PWC 264
+ * Task 1
+ * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+ *
+ *
+ * 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/PWC264-1.jar luca@rachel:/tmp
+
+
+ * To install into PostgreSQL execute:
+
+ select sqlj.install_jar( 'file:///tmp/PWC264-1.jar', 'PWC264', true );
+ select sqlj.set_classpath( 'public', 'PWC264' );
+
+ select pwc264.task2_pljava();
+
+ and then to redeploy:
+
+ select sqlj.replace_jar( 'file:///tmp/PWC264-1.jar', 'PWC264', 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;
+import java.util.regex.*;
+
+public class Task1 {
+
+ private final static Logger logger = Logger.getAnonymousLogger();
+
+ @Function( schema = "pwc264",
+ onNullInput = RETURNS_NULL,
+ effects = IMMUTABLE )
+ public static final String task1_pljava( String string ) throws SQLException {
+ logger.log( Level.INFO, "Entering pwc264.task1_pljava" );
+
+ List<String> letters = new LinkedList<String>();
+ for ( String l : string.split( "" ) ) {
+ if ( ! l.equals( l.toUpperCase() ) )
+ continue;
+
+ Pattern regexp = Pattern.compile( l.toLowerCase() );
+ Matcher engine = regexp.matcher( string );
+ if ( ! engine.matches() )
+ letters.add( l );
+ }
+
+ if ( letters.isEmpty() )
+ return "-";
+
+ Collections.sort( letters );
+ return letters.get( letters.size() - 1 );
+ }
+}
diff --git a/challenge-264/luca-ferrari/pljava/src/main/java/Task2.java b/challenge-264/luca-ferrari/pljava/src/main/java/Task2.java
new file mode 100644
index 0000000000..718e4e61ca
--- /dev/null
+++ b/challenge-264/luca-ferrari/pljava/src/main/java/Task2.java
@@ -0,0 +1,79 @@
+
+
+
+package PWC264;
+
+/**
+ * PL/Java implementation for PWC 264
+ * Task 2
+ * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+ *
+ *
+ * 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/PWC264-1.jar luca@rachel:/tmp
+
+
+ * To install into PostgreSQL execute:
+
+ select sqlj.install_jar( 'file:///tmp/PWC264-1.jar', 'PWC264', true );
+ select sqlj.set_classpath( 'public', 'PWC264' );
+
+ select pwc264.task2_pljava();
+
+ and then to redeploy:
+
+ select sqlj.replace_jar( 'file:///tmp/PWC264-1.jar', 'PWC264', 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 = "pwc264",
+ onNullInput = RETURNS_NULL,
+ effects = IMMUTABLE )
+ public static final int[] task2_pljava( int[] source, int[] indexes ) throws SQLException {
+ logger.log( Level.INFO, "Entering pwc264.task2_pljava" );
+
+ List<Integer> target = new LinkedList<Integer>();
+
+ for ( int i = 0; i < indexes.length; i++ ) {
+ int target_index = indexes[ i ];
+ if ( target.isEmpty() || target.size() <= target_index )
+ target.add( source[ i ] );
+ else {
+ List<Integer> replace = new LinkedList<Integer>();
+ for ( int ii = 0; ii < target_index; ii++ )
+ replace.add( target.get( ii ) );
+ replace.add( source[ i ] );
+ for ( int ii = target_index; ii < target.size(); ii++ )
+ replace.add( target.get( ii ) );
+
+ target = replace;
+ }
+ }
+
+ int[] result = new int[ target.size() ];
+ int k = 0;
+ for ( int v : target )
+ result[ k++ ] = v;
+
+ return result;
+ }
+}
diff --git a/challenge-264/luca-ferrari/plperl/ch-1.plperl b/challenge-264/luca-ferrari/plperl/ch-1.plperl
new file mode 100644
index 0000000000..ffa4937991
--- /dev/null
+++ b/challenge-264/luca-ferrari/plperl/ch-1.plperl
@@ -0,0 +1,28 @@
+--
+-- Perl Weekly Challenge 264
+-- Task 1
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc264;
+
+CREATE OR REPLACE FUNCTION
+pwc264.task1_plperl( text )
+RETURNS char
+AS $CODE$
+
+ my ( $string ) = @_;
+ die "Must contain only letters" if ( ! $string =~ /^[a-zA-Z]+$/ );
+
+ my @letters;
+ for my $letter ( grep( { $_ =~ /[A-Z]/ } split( //, $string ) ) ) {
+ my $lc_letter = lc $letter;
+ next if $string !~ /$lc_letter/;
+ push @letters, $letter;
+ }
+
+ return '' if ! @letters;
+ return ( sort( @letters ) )[ -1 ];
+
+$CODE$
+LANGUAGE plperl;
diff --git a/challenge-264/luca-ferrari/plperl/ch-2.plperl b/challenge-264/luca-ferrari/plperl/ch-2.plperl
new file mode 100644
index 0000000000..df41af33b6
--- /dev/null
+++ b/challenge-264/luca-ferrari/plperl/ch-2.plperl
@@ -0,0 +1,48 @@
+--
+-- Perl Weekly Challenge 264
+-- Task 2
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc264;
+
+/**
+ * Exdample of invocation
+
+testdb=> select pwc264.task2_plperl( array[0, 1, 2, 3, 4], array[0, 1, 2, 2, 1] );
+ task2_plperl
+--------------
+ {0,4,1,3,2}
+
+*/
+CREATE OR REPLACE FUNCTION
+pwc264.task2_plperl( int[], int[] )
+RETURNS int[]
+AS $CODE$
+
+ my ( $source, $indexes ) = @_;
+
+ die "Array must have the same size!" if ( scalar( $source->@* ) != scalar( $indexes->@* ) );
+ for ( $indexes->@* ) {
+ next if $_ >= 0 && $_ <= scalar( $source->@* );
+ die "Array indexes must be contained in the source array"
+ }
+
+
+ my @target;
+
+ for my $index ( 0 .. $indexes->@* - 1 ) {
+ my $target_index = $indexes->@[ $index ];
+
+ if ( ! $target[ $target_index ] ) {
+ push @target, $source->@[ $index ];
+ }
+ else {
+ @target = ( @target[ 0 .. $target_index - 1 ], $source->@[ $index ], @target[ $target_index .. $#target ] );
+ }
+ }
+
+ return [ @target ];
+
+$CODE$
+LANGUAGE plperl;
diff --git a/challenge-264/luca-ferrari/plpgsql/ch-1.sql b/challenge-264/luca-ferrari/plpgsql/ch-1.sql
new file mode 100644
index 0000000000..10a0eaca35
--- /dev/null
+++ b/challenge-264/luca-ferrari/plpgsql/ch-1.sql
@@ -0,0 +1,42 @@
+--
+-- Perl Weekly Challenge 264
+-- Task 1
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc264;
+
+CREATE OR REPLACE FUNCTION
+pwc264.task1_plpgsql( s text )
+RETURNS char
+AS $CODE$
+DECLARE
+ letter char;
+BEGIN
+ CREATE TEMPORARY TABLE IF NOT EXISTS letters( l char, ok boolean default false );
+ TRUNCATE letters;
+
+ INSERT INTO letters
+ SELECT v
+ FROM regexp_split_to_table( s, '' ) v
+ WHERE v ~ '[A-Z]'
+ GROUP BY v;
+
+ FOR letter IN SELECT v::char FROM regexp_split_to_table( s, '[a-z]' ) v LOOP
+ UPDATE letters
+ SET ok = true
+ WHERE ok = false
+ AND l = upper( letter );
+ END LOOP;
+
+ SELECT l
+ INTO letter
+ FROM letters
+ WHERE ok
+ ORDER BY 1 DESC
+ LIMIT 1;
+
+ RETURN letter;
+END
+$CODE$
+LANGUAGE plpgsql;
diff --git a/challenge-264/luca-ferrari/plpgsql/ch-2.sql b/challenge-264/luca-ferrari/plpgsql/ch-2.sql
new file mode 100644
index 0000000000..39c15556ac
--- /dev/null
+++ b/challenge-264/luca-ferrari/plpgsql/ch-2.sql
@@ -0,0 +1,46 @@
+--
+-- Perl Weekly Challenge 264
+-- Task 2
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc264;
+
+CREATE OR REPLACE FUNCTION
+pwc264.task2_plpgsql( s_a int[], i_a int[] )
+RETURNS SETOF int
+AS $CODE$
+DECLARE
+ target_index int;
+ current_index int;
+BEGIN
+ CREATE TEMPORARY TABLE IF NOT EXISTS target( i int, v int );
+ TRUNCATE target;
+
+ FOR current_index IN SELECT v::int FROM unnest( i_a ) v LOOP
+ target_index := i_a[ current_index ];
+
+ PERFORM *
+ FROM target
+ WHERE i = target_index;
+
+ IF FOUND THEN
+ UPDATE target
+ SET i = i + 1
+ WHERE i >= target_index;
+
+ END IF;
+
+ INSERT INTO target( i, v )
+ VALUES ( target_index, s_a[ current_index ] );
+
+ END LOOP;
+
+ RETURN QUERY
+ SELECT v
+ FROM target
+ ORDER BY i;
+
+END
+$CODE$
+LANGUAGE plpgsql;
diff --git a/challenge-264/luca-ferrari/python/ch-1.py b/challenge-264/luca-ferrari/python/ch-1.py
new file mode 100644
index 0000000000..7fb68142f6
--- /dev/null
+++ b/challenge-264/luca-ferrari/python/ch-1.py
@@ -0,0 +1,38 @@
+#!python
+
+#
+# Perl Weekly Challenge 264
+# Task 1
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+#
+
+import sys
+import re
+
+# task implementation
+# the return value will be printed
+def task_1( args ):
+ string = args[ 0 ]
+ letters = []
+
+ for letter in string:
+ if not letter.isupper():
+ continue
+
+ engine = re.compile( letter.lower() )
+ if not engine.search( string ):
+ continue
+
+ letters.append( letter )
+
+ if len( letters ) <= 0:
+ return ''
+
+ letters.sort()
+ return letters[ len( letters ) - 1 ]
+
+
+# invoke the main without the command itself
+if __name__ == '__main__':
+ print( task_1( sys.argv[ 1: ] ) )
diff --git a/challenge-264/luca-ferrari/python/ch-2.py b/challenge-264/luca-ferrari/python/ch-2.py
new file mode 100644
index 0000000000..3813d5710e
--- /dev/null
+++ b/challenge-264/luca-ferrari/python/ch-2.py
@@ -0,0 +1,46 @@
+#!python
+
+#
+# Perl Weekly Challenge 264
+# Task 2
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+#
+
+import sys
+
+# task implementation
+# the return value will be printed
+def task_2( args ):
+ source = []
+ indexes = []
+ target = []
+ swap = False
+ for v in args:
+ if v == '|':
+ swap = True
+ continue
+ else:
+ if swap:
+ indexes.append( int( v ) )
+ else:
+ source.append( int( v ) )
+
+
+ for i in range( 0, len( indexes ) ):
+ target_index = indexes[ i ]
+ if len( target ) <= target_index:
+ target.insert( target_index, source[ i ] )
+ else:
+ swapper = []
+ swapper = target[ 0 : target_index ]
+ swapper.append( source[ i ] )
+ swapper += target[ target_index : ]
+ target = swapper
+
+
+ return target
+
+# invoke the main without the command itself
+if __name__ == '__main__':
+ print( task_2( sys.argv[ 1: ] ) )
diff --git a/challenge-264/luca-ferrari/raku/ch-1.raku b/challenge-264/luca-ferrari/raku/ch-1.raku
new file mode 100644
index 0000000000..442d44a192
--- /dev/null
+++ b/challenge-264/luca-ferrari/raku/ch-1.raku
@@ -0,0 +1,19 @@
+#!raku
+
+#
+# Perl Weekly Challenge 264
+# Task 1
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+#
+
+sub MAIN( Str $string where { $string ~~ / ^ <[a..zA..Z]>+ $ / } ) {
+ my @letters;
+
+ for $string.comb.grep( * ~~ / <[A..Z]> / ) -> $letter {
+ next if ! $string ~~ / $letter.lc /;
+ @letters.push: $letter;
+ }
+
+ @letters.sort[ * - 1 ].say if ( @letters );
+}
diff --git a/challenge-264/luca-ferrari/raku/ch-2.raku b/challenge-264/luca-ferrari/raku/ch-2.raku
new file mode 100644
index 0000000000..c113909cd5
--- /dev/null
+++ b/challenge-264/luca-ferrari/raku/ch-2.raku
@@ -0,0 +1,31 @@
+#!raku
+
+#
+# Perl Weekly Challenge 264
+# Task 2
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-264>
+#
+
+# example of invocation
+# $ raku raku/ch-2.raku --source 0 --source 1 --source 2 --source 3 --source 4 --indexes 0 --indexes 1 --indexes 2 --indexes 2 --indexes 1
+# 0 4 1 3 2
+
+sub MAIN( :@source, :@indexes
+ where { @source.elems == @indexes.elems
+ && @indexes.min >= 0
+ && @indexes.max <= @source.elems } ) {
+
+ my @target;
+
+ for 0 ..^ @indexes.elems {
+ my $target-index = @indexes[ $_ ];
+ if ! @target[ $target-index ] {
+ @target[ $target-index ] = @source[ $_ ];
+ } else {
+ @target = |@target[ 0 .. $target-index - 1 ], @source[ $_ ], |@target[ $target-index .. * ];
+ }
+ }
+
+ @target.join( ' ' ).say;
+}