aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Ferrari <fluca1978@gmail.com>2025-07-10 12:38:23 +0200
committerLuca Ferrari <fluca1978@gmail.com>2025-07-10 14:26:28 +0200
commit4bdf01fc828095304e3d85ddd3c2af8d2e7ade08 (patch)
treeaeb2de9c23a0e6c0dfeeee86805e480c80c319ac
parent6a1bc860b02b7d2b0b1806cb9aa6a1e00a2d966e (diff)
downloadperlweeklychallenge-club-4bdf01fc828095304e3d85ddd3c2af8d2e7ade08.tar.gz
perlweeklychallenge-club-4bdf01fc828095304e3d85ddd3c2af8d2e7ade08.tar.bz2
perlweeklychallenge-club-4bdf01fc828095304e3d85ddd3c2af8d2e7ade08.zip
PWC 329
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-329/luca-ferrari/blog-1.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-10.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-2.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-3.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-4.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-5.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-6.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-7.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-8.txt1
-rw-r--r--challenge-329/luca-ferrari/blog-9.txt1
-rw-r--r--challenge-329/luca-ferrari/pljava/pom.xml72
-rw-r--r--challenge-329/luca-ferrari/pljava/src/main/java/Task1.java72
-rw-r--r--challenge-329/luca-ferrari/pljava/src/main/java/Task2.java77
-rw-r--r--challenge-329/luca-ferrari/plperl/ch-1.plperl26
-rw-r--r--challenge-329/luca-ferrari/plperl/ch-2.plperl36
-rw-r--r--challenge-329/luca-ferrari/plpgsql/ch-1.sql17
-rw-r--r--challenge-329/luca-ferrari/plpgsql/ch-2.sql50
-rw-r--r--challenge-329/luca-ferrari/python/ch-1.py28
-rw-r--r--challenge-329/luca-ferrari/python/ch-2.py38
-rw-r--r--challenge-329/luca-ferrari/raku/ch-1.raku17
-rw-r--r--challenge-329/luca-ferrari/raku/ch-2.raku28
21 files changed, 471 insertions, 0 deletions
diff --git a/challenge-329/luca-ferrari/blog-1.txt b/challenge-329/luca-ferrari/blog-1.txt
new file mode 100644
index 0000000000..c103669812
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-1.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task1
diff --git a/challenge-329/luca-ferrari/blog-10.txt b/challenge-329/luca-ferrari/blog-10.txt
new file mode 100644
index 0000000000..050968a099
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-10.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task2pljava
diff --git a/challenge-329/luca-ferrari/blog-2.txt b/challenge-329/luca-ferrari/blog-2.txt
new file mode 100644
index 0000000000..cb5d8fdced
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-2.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task2
diff --git a/challenge-329/luca-ferrari/blog-3.txt b/challenge-329/luca-ferrari/blog-3.txt
new file mode 100644
index 0000000000..d8473ae954
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-3.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task1plperl
diff --git a/challenge-329/luca-ferrari/blog-4.txt b/challenge-329/luca-ferrari/blog-4.txt
new file mode 100644
index 0000000000..f6c0a4e818
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-4.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task2plperl
diff --git a/challenge-329/luca-ferrari/blog-5.txt b/challenge-329/luca-ferrari/blog-5.txt
new file mode 100644
index 0000000000..6bf000f25d
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-5.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task1plpgsql
diff --git a/challenge-329/luca-ferrari/blog-6.txt b/challenge-329/luca-ferrari/blog-6.txt
new file mode 100644
index 0000000000..dece5a0d40
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-6.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task2plpgsql
diff --git a/challenge-329/luca-ferrari/blog-7.txt b/challenge-329/luca-ferrari/blog-7.txt
new file mode 100644
index 0000000000..85aaf18b1f
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-7.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task1python
diff --git a/challenge-329/luca-ferrari/blog-8.txt b/challenge-329/luca-ferrari/blog-8.txt
new file mode 100644
index 0000000000..a4fa19214a
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-8.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task2python
diff --git a/challenge-329/luca-ferrari/blog-9.txt b/challenge-329/luca-ferrari/blog-9.txt
new file mode 100644
index 0000000000..13043a9c24
--- /dev/null
+++ b/challenge-329/luca-ferrari/blog-9.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2025/07/10/PerlWeeklyChallenge329.html#task1pljava
diff --git a/challenge-329/luca-ferrari/pljava/pom.xml b/challenge-329/luca-ferrari/pljava/pom.xml
new file mode 100644
index 0000000000..1397948409
--- /dev/null
+++ b/challenge-329/luca-ferrari/pljava/pom.xml
@@ -0,0 +1,72 @@
+
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>PWC</groupId>
+ <artifactId>
+ PWC329
+ </artifactId>
+ <version>
+ 1
+ </version>
+
+ <name>Perl Weekly Challenge 329 with package PWC329</name>
+ <description>Implementation of the tasks in PL/Java for PWC 329</description>
+
+ <properties>
+ <project.build.sourceEncoding>US-ASCII</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.postgresql</groupId>
+ <artifactId>pljava-api</artifactId>
+ <version>1.6.6</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <release>9</release>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <!-- This identifies and version-stamps the jar.
+ Not essential, but easy and useful. -->
+ <addDefaultImplementationEntries>
+ true
+ </addDefaultImplementationEntries>
+ </manifest>
+
+ <manifestSections>
+ <!-- This identifies a file in the jar named
+ pljava.ddr as an SQLJDeploymentDescriptor. -->
+ <manifestSection>
+ <name>pljava.ddr</name>
+ <manifestEntries>
+ <SQLJDeploymentDescriptor>
+ true
+ </SQLJDeploymentDescriptor>
+ </manifestEntries>
+ </manifestSection>
+ </manifestSections>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/challenge-329/luca-ferrari/pljava/src/main/java/Task1.java b/challenge-329/luca-ferrari/pljava/src/main/java/Task1.java
new file mode 100644
index 0000000000..be4e77e6fc
--- /dev/null
+++ b/challenge-329/luca-ferrari/pljava/src/main/java/Task1.java
@@ -0,0 +1,72 @@
+
+
+
+package PWC329;
+
+/**
+ * PL/Java implementation for PWC 329
+ * Task 1
+ * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+ *
+ *
+ * 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/PWC329-1.jar luca@rachel:/tmp
+
+
+ * To install into PostgreSQL execute:
+
+ select sqlj.install_jar( 'file:///tmp/PWC329-1.jar', 'PWC329', true );
+ select sqlj.set_classpath( 'public', 'PWC329' );
+
+ select pwc329.task2_pljava();
+
+ and then to redeploy:
+
+ select sqlj.replace_jar( 'file:///tmp/PWC329-1.jar', 'PWC329', 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 = "pwc329",
+ onNullInput = RETURNS_NULL,
+ effects = IMMUTABLE )
+ public static final int[] task1_pljava( String string ) throws SQLException {
+ logger.log( Level.INFO, "Entering pwc329.task1_pljava" );
+
+ Map<Integer, Integer> numbers = new HashMap<Integer, Integer>();
+
+ Pattern regexp = Pattern.compile( "\\d+" );
+ Matcher engine = regexp.matcher( string );
+ while ( engine.find() ) {
+ try {
+ numbers.put( Integer.parseInt( engine.group() ), 1 );
+ } catch( Exception e ) { }
+ }
+
+ int result[] = new int[ numbers.size() ];
+ int j = 0;
+ for ( int i : numbers.keySet() )
+ result[ j++ ] = i;
+
+ return result;
+ }
+}
diff --git a/challenge-329/luca-ferrari/pljava/src/main/java/Task2.java b/challenge-329/luca-ferrari/pljava/src/main/java/Task2.java
new file mode 100644
index 0000000000..64956c8ab5
--- /dev/null
+++ b/challenge-329/luca-ferrari/pljava/src/main/java/Task2.java
@@ -0,0 +1,77 @@
+
+
+
+package PWC329;
+
+/**
+ * PL/Java implementation for PWC 329
+ * Task 2
+ * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+ *
+ *
+ * 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/PWC329-1.jar luca@rachel:/tmp
+
+
+ * To install into PostgreSQL execute:
+
+ select sqlj.install_jar( 'file:///tmp/PWC329-1.jar', 'PWC329', true );
+ select sqlj.set_classpath( 'public', 'PWC329' );
+
+ select pwc329.task2_pljava();
+
+ and then to redeploy:
+
+ select sqlj.replace_jar( 'file:///tmp/PWC329-1.jar', 'PWC329', 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 Task2 {
+
+ private final static Logger logger = Logger.getAnonymousLogger();
+
+ @Function( schema = "pwc329",
+ onNullInput = RETURNS_NULL,
+ effects = IMMUTABLE )
+ public static final String task2_pljava( String string ) throws SQLException {
+ logger.log( Level.INFO, "Entering pwc329.task2_pljava" );
+
+
+ char chars[] = string.toCharArray();
+
+ int begin = 0;
+ int end = 0;
+
+ for ( int i = 0; i < chars.length; i++ ) {
+ char c = chars[ i ];
+ char n = Character.toUpperCase( c );
+ if ( Character.isUpperCase( c ) )
+ n = Character.toLowerCase( c );
+
+ for ( int j = i + 1; j < chars.length; j++ )
+ if ( chars[ j ] == n )
+ if ( ( end - begin ) < ( j - i ) ) {
+ begin = i;
+ end = j;
+ }
+ }
+
+ return string.substring( begin, end + 1 );
+ }
+}
diff --git a/challenge-329/luca-ferrari/plperl/ch-1.plperl b/challenge-329/luca-ferrari/plperl/ch-1.plperl
new file mode 100644
index 0000000000..15feb485ed
--- /dev/null
+++ b/challenge-329/luca-ferrari/plperl/ch-1.plperl
@@ -0,0 +1,26 @@
+--
+-- Perl Weekly Challenge 329
+-- Task 1
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc329;
+
+CREATE OR REPLACE FUNCTION
+pwc329.task1_plperl( text )
+RETURNS SETOF int
+AS $CODE$
+
+ my ( $string ) = @_;
+ die "Invalid string" unless( $string =~ / ^ [a-zA-Z0-9]+ $ /x );
+
+ my $found = {};
+
+ for ( $string =~ / [0-9]+ /xg ) {
+ $found->{ $_ }++;
+ }
+
+ return [ sort keys $found->%* ];
+
+$CODE$
+LANGUAGE plperl;
diff --git a/challenge-329/luca-ferrari/plperl/ch-2.plperl b/challenge-329/luca-ferrari/plperl/ch-2.plperl
new file mode 100644
index 0000000000..dc112b57dd
--- /dev/null
+++ b/challenge-329/luca-ferrari/plperl/ch-2.plperl
@@ -0,0 +1,36 @@
+--
+-- Perl Weekly Challenge 329
+-- Task 2
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc329;
+
+CREATE OR REPLACE FUNCTION
+pwc329.task2_plperl( text )
+RETURNS text
+AS $CODE$
+
+ my ( $string ) = @_;
+ die "Invalid string" unless( $string =~ / ^ [a-zA-Z]+ $ /x );
+
+ my $found;
+ my @chars = split //, $string;
+ for my $i ( 0 .. $#chars ) {
+ my $current = $chars[ $i ];
+ my $needle = uc $current;
+ $needle = lc $current if ( $current =~ /[A-Z]/ );
+ my $index = 0;
+
+ my $index = ( sort
+ map { $_->[ 1 ] }
+ grep { $_->[ 0 ] eq $needle }
+ map { [ $_, $index++ ] } @chars[ $i .. $#chars ] )[ -1 ];
+ my $match = join( '', @chars[ $i .. $index ] );
+ $found = $match if ( ! $found || length( $found ) < length( $match ) );
+ }
+
+ return $found;
+
+$CODE$
+LANGUAGE plperl;
diff --git a/challenge-329/luca-ferrari/plpgsql/ch-1.sql b/challenge-329/luca-ferrari/plpgsql/ch-1.sql
new file mode 100644
index 0000000000..8b35d46253
--- /dev/null
+++ b/challenge-329/luca-ferrari/plpgsql/ch-1.sql
@@ -0,0 +1,17 @@
+--
+-- Perl Weekly Challenge 329
+-- Task 1
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc329;
+
+CREATE OR REPLACE FUNCTION
+pwc329.task1_plpgsql( s text )
+RETURNS SETOF text
+AS $CODE$
+ SELECT distinct( v )
+ FROM regexp_matches( s, '\d+', 'g' ) v
+ ORDER BY 1
+$CODE$
+LANGUAGE sql;
diff --git a/challenge-329/luca-ferrari/plpgsql/ch-2.sql b/challenge-329/luca-ferrari/plpgsql/ch-2.sql
new file mode 100644
index 0000000000..6a7f8ee510
--- /dev/null
+++ b/challenge-329/luca-ferrari/plpgsql/ch-2.sql
@@ -0,0 +1,50 @@
+--
+-- Perl Weekly Challenge 329
+-- Task 2
+-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+--
+
+CREATE SCHEMA IF NOT EXISTS pwc329;
+
+CREATE OR REPLACE FUNCTION
+pwc329.task2_plpgsql( s text )
+RETURNS text
+AS $CODE$
+DECLARE
+ current text;
+ i int;
+ chars text[];
+ result text;
+ tmp text;
+ needle text;
+BEGIN
+
+ SELECT regexp_split_to_array( s, '' )
+ INTO chars;
+
+ result := '';
+
+ FOR i in 1 .. length( s ) LOOP
+ current := chars[ i ];
+ needle := upper( current );
+
+ IF current ~ '[A-Z]' THEN
+ needle := lower( current );
+ END IF;
+
+ tmp := '';
+ FOR j IN i .. length( s ) LOOP
+ IF chars[ j ] = needle THEN
+ tmp := array_to_string( chars[ i : j ], '' );
+ IF length( tmp ) > length( result ) THEN
+ result := tmp;
+ END IF;
+ END IF;
+ END LOOP;
+
+ END LOOP;
+
+ RETURN result;
+END
+$CODE$
+LANGUAGE plpgsql;
diff --git a/challenge-329/luca-ferrari/python/ch-1.py b/challenge-329/luca-ferrari/python/ch-1.py
new file mode 100644
index 0000000000..41d2e6a1d8
--- /dev/null
+++ b/challenge-329/luca-ferrari/python/ch-1.py
@@ -0,0 +1,28 @@
+#!python
+
+#
+# Perl Weekly Challenge 329
+# Task 1
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+#
+
+import sys
+import re
+
+# task implementation
+# the return value will be printed
+def task_1( args ):
+ string = args[ 0 ]
+
+ numbers = []
+ pattern = re.compile( r'\d+' )
+ for i in pattern.findall( string ) :
+ if not i in numbers :
+ numbers.append( i )
+
+ return numbers
+
+# invoke the main without the command itself
+if __name__ == '__main__':
+ print( task_1( sys.argv[ 1: ] ) )
diff --git a/challenge-329/luca-ferrari/python/ch-2.py b/challenge-329/luca-ferrari/python/ch-2.py
new file mode 100644
index 0000000000..bdfc275a82
--- /dev/null
+++ b/challenge-329/luca-ferrari/python/ch-2.py
@@ -0,0 +1,38 @@
+#!python
+
+#
+# Perl Weekly Challenge 329
+# Task 2
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+#
+
+import sys
+
+# task implementation
+# the return value will be printed
+def task_2( args ):
+ string = args[ 0 ]
+
+ begin = 0
+ end = 0
+
+ for i in range( 0, len( string ) - 1 ) :
+ current = string[ i ]
+ needle = current.upper()
+ if current.isupper() :
+ needle = current.lower()
+
+ for j in range( i + 1, len( string ) ) :
+ print( " => ", string[ j ] )
+ if string[ j ] == needle :
+ if ( end - begin ) < ( j - i ) :
+ begin = i
+ end = j
+
+ return string[ begin : end + 1 ]
+
+
+# invoke the main without the command itself
+if __name__ == '__main__':
+ print( task_2( sys.argv[ 1: ] ) )
diff --git a/challenge-329/luca-ferrari/raku/ch-1.raku b/challenge-329/luca-ferrari/raku/ch-1.raku
new file mode 100644
index 0000000000..cdaeb1f1e8
--- /dev/null
+++ b/challenge-329/luca-ferrari/raku/ch-1.raku
@@ -0,0 +1,17 @@
+#!raku
+
+#
+# Perl Weekly Challenge 329
+# Task 1
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+#
+
+sub MAIN( Str $string where { $string ~~ / <[a..zA..Z0..9]>+ / } ) {
+ my %digits;
+ for ( $string ~~ m:g/ <[0..9]>+ / ).values {
+ %digits{ $_ }++;
+ }
+
+ %digits.keys.sort.join( ',' ).say;
+}
diff --git a/challenge-329/luca-ferrari/raku/ch-2.raku b/challenge-329/luca-ferrari/raku/ch-2.raku
new file mode 100644
index 0000000000..e5b5f9de4c
--- /dev/null
+++ b/challenge-329/luca-ferrari/raku/ch-2.raku
@@ -0,0 +1,28 @@
+#!raku
+
+#
+# Perl Weekly Challenge 329
+# Task 2
+#
+# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-329>
+#
+
+sub MAIN( Str $string where { $string ~~ / <[a..zA..Z]>+ / } ) {
+ exit( 0 ) if $string.chars <= 1;
+
+ my @chars = $string.comb;
+ my $found;
+
+ for 0 ..^ @chars.elems {
+ my $current = @chars[ $_ ];
+ my $needle = $current.uc;
+ $needle = $current.lc if ( $current ~~ / <[A..Z]> / );
+
+ my $last-index = @chars[ $_ .. * - 1 ].grep( * ~~ $needle, :k ).max;
+ my $match = @chars[ $_ .. $last-index ].join;
+ $found = $match if ( ! $found || $match.chars > $found.chars );
+ }
+
+ $found.say;
+
+}