diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-11-14 17:12:35 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-14 17:12:35 +0000 |
| commit | e4f95af26374a568704a6256fd8a94343961f62e (patch) | |
| tree | 4cefe6a3367eb72c44695feee958987c0f607ac8 | |
| parent | 349fcb363ce1d6422484849a9a118baff2eb1827 (diff) | |
| parent | ff9bf5ea41fe76a7c1acf1abe0b5b57b538e309d (diff) | |
| download | perlweeklychallenge-club-e4f95af26374a568704a6256fd8a94343961f62e.tar.gz perlweeklychallenge-club-e4f95af26374a568704a6256fd8a94343961f62e.tar.bz2 perlweeklychallenge-club-e4f95af26374a568704a6256fd8a94343961f62e.zip | |
Merge pull request #13026 from fluca1978/PWC347
PWC 347
21 files changed, 568 insertions, 0 deletions
diff --git a/challenge-347/luca-ferrari/blog-1.txt b/challenge-347/luca-ferrari/blog-1.txt new file mode 100644 index 0000000000..7d8a425d20 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-1.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task1 diff --git a/challenge-347/luca-ferrari/blog-10.txt b/challenge-347/luca-ferrari/blog-10.txt new file mode 100644 index 0000000000..04cc9108ed --- /dev/null +++ b/challenge-347/luca-ferrari/blog-10.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task2pljava diff --git a/challenge-347/luca-ferrari/blog-2.txt b/challenge-347/luca-ferrari/blog-2.txt new file mode 100644 index 0000000000..5e1ea3d0ae --- /dev/null +++ b/challenge-347/luca-ferrari/blog-2.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task2 diff --git a/challenge-347/luca-ferrari/blog-3.txt b/challenge-347/luca-ferrari/blog-3.txt new file mode 100644 index 0000000000..c6a4d84329 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-3.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task1plperl diff --git a/challenge-347/luca-ferrari/blog-4.txt b/challenge-347/luca-ferrari/blog-4.txt new file mode 100644 index 0000000000..53e0f402b9 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-4.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task2plperl diff --git a/challenge-347/luca-ferrari/blog-5.txt b/challenge-347/luca-ferrari/blog-5.txt new file mode 100644 index 0000000000..630d6544d0 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-5.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task1plpgsql diff --git a/challenge-347/luca-ferrari/blog-6.txt b/challenge-347/luca-ferrari/blog-6.txt new file mode 100644 index 0000000000..d8edbc7ad7 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-6.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task2plpgsql diff --git a/challenge-347/luca-ferrari/blog-7.txt b/challenge-347/luca-ferrari/blog-7.txt new file mode 100644 index 0000000000..129ddd3b22 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-7.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task1python diff --git a/challenge-347/luca-ferrari/blog-8.txt b/challenge-347/luca-ferrari/blog-8.txt new file mode 100644 index 0000000000..a8c07374ae --- /dev/null +++ b/challenge-347/luca-ferrari/blog-8.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task2python diff --git a/challenge-347/luca-ferrari/blog-9.txt b/challenge-347/luca-ferrari/blog-9.txt new file mode 100644 index 0000000000..a61297e251 --- /dev/null +++ b/challenge-347/luca-ferrari/blog-9.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2025/11/13/PerlWeeklyChallenge347.html#task1pljava diff --git a/challenge-347/luca-ferrari/pljava/pom.xml b/challenge-347/luca-ferrari/pljava/pom.xml new file mode 100644 index 0000000000..9d238d7670 --- /dev/null +++ b/challenge-347/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> + PWC347 + </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> + + <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-347/luca-ferrari/pljava/src/main/java/Task1.java b/challenge-347/luca-ferrari/pljava/src/main/java/Task1.java new file mode 100644 index 0000000000..55a579ff0f --- /dev/null +++ b/challenge-347/luca-ferrari/pljava/src/main/java/Task1.java @@ -0,0 +1,76 @@ + + + +package PWC347; + +/** + * PL/Java implementation for PWC 347 + * Task 1 + * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> + * + * + * 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/PWC347-1.jar luca@rachel:/tmp + + + * To install into PostgreSQL execute: + + select sqlj.install_jar( 'file:///tmp/PWC347-1.jar', 'PWC347', true ); + select sqlj.set_classpath( 'public', 'PWC347' ); + + select pwc347.task2_pljava(); + + and then to redeploy: + + select sqlj.replace_jar( 'file:///tmp/PWC347-1.jar', 'PWC347', 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 = "pwc347", + onNullInput = RETURNS_NULL, + effects = IMMUTABLE ) + public static final String task1_pljava( String date ) throws SQLException { + logger.log( Level.INFO, "Entering pwc347.task1_pljava" ); + + Map<String, Integer> months = new HashMap<String, Integer>(); + + months.put( "Jan", 1 ); + months.put( "Feb", 2 ); + months.put( "Mar", 3 ); + months.put( "Apr", 4 ); + months.put( "May", 5 ); + months.put( "Jun", 6 ); + months.put( "Jul", 7 ); + months.put( "Aug", 8 ); + months.put( "Sep", 9 ); + months.put( "Oct", 10 ); + months.put( "Nov", 11 ); + months.put( "Dec", 12 ); + + + String[] parts = date.split( "\\s+" ); + return String.format( "%04d-%02d-%02d", + Integer.parseInt( parts[ 2 ] ), + months.get( parts[ 1 ] ), + Integer.parseInt( parts[ 0 ].replace( "st", "" ).replace( "nd", "" ).replace( "rd", "" ).replace( "rh", "" ) ) ); + } +} diff --git a/challenge-347/luca-ferrari/pljava/src/main/java/Task2.java b/challenge-347/luca-ferrari/pljava/src/main/java/Task2.java new file mode 100644 index 0000000000..b51d95c8d2 --- /dev/null +++ b/challenge-347/luca-ferrari/pljava/src/main/java/Task2.java @@ -0,0 +1,92 @@ + + + +package PWC347; + +/** + * PL/Java implementation for PWC 347 + * Task 2 + * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> + * + * + * 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/PWC347-1.jar luca@rachel:/tmp + + + * To install into PostgreSQL execute: + + select sqlj.install_jar( 'file:///tmp/PWC347-1.jar', 'PWC347', true ); + select sqlj.set_classpath( 'public', 'PWC347' ); + + select pwc347.task2_pljava(); + + and then to redeploy: + + select sqlj.replace_jar( 'file:///tmp/PWC347-1.jar', 'PWC347', 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 = "pwc347", + onNullInput = RETURNS_NULL, + effects = IMMUTABLE ) + public static final String task2_pljava( String phone ) throws SQLException { + logger.log( Level.INFO, "Entering pwc347.task2_pljava" ); + + phone = phone.replaceAll( "-", "" ).replaceAll( " ", "" ); + List<String> groups = new LinkedList<String>(); + + String current = ""; + for( int i = 0; i < phone.length(); i++ ) { + current += phone.charAt( i ); + if ( current.length() % 3 == 0 ) { + groups.add( current ); + current = ""; + } + } + + if ( current.length() > 0 ) { + groups.add( current ); + } + + + if ( groups.get( groups.size() - 1 ).length() != 2 + || groups.get( groups.size() - 1 ).length() != 3 ) { + + String begin = groups.get( groups.size() - 2 ); + String end = groups.get( groups.size() - 1 ); + groups.remove( groups.size() - 1 ); + groups.remove( groups.size() - 1 ); + + String last = begin + end; + + groups.add( "" + last.charAt( 0 ) + last.charAt( 1 ) ); + groups.add( "" + last.charAt( 2 ) + last.charAt( 3 ) ); + } + + String result = ""; + for ( String s : groups ) { + result += s + "-"; + } + + return result; + } +} diff --git a/challenge-347/luca-ferrari/plperl/ch-1.plperl b/challenge-347/luca-ferrari/plperl/ch-1.plperl new file mode 100644 index 0000000000..c41ffa56a7 --- /dev/null +++ b/challenge-347/luca-ferrari/plperl/ch-1.plperl @@ -0,0 +1,39 @@ +-- +-- Perl Weekly Challenge 347 +-- Task 1 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +-- + +CREATE SCHEMA IF NOT EXISTS pwc347; + +CREATE OR REPLACE FUNCTION +pwc347.task1_plperl( text ) +RETURNS date +AS $CODE$ + + my ( $date ) = @_; + + my %months = ( 'Jan' => 1, + 'Feb' => 2, + 'Mar' => 3, + 'Apr' => 4, + 'May' => 5, + 'Jun' => 6, + 'Jul' => 7, + 'Aug' => 8, + 'Sep' => 9, + 'Oct' => 10, + 'Nov' => 11, + 'Dec' => 12 ); + + if ( $date =~ / ^ (?<day>\d{1,2}) \D{2} \s+ (?<month>\D{3}) \s+ (?<year>\d{4}) $ /x ) { + return sprintf '%04d-%02d-%02d', $+{year}, $months{ $+{month} }, $+{day}; + } + else { + elog( WARN, "No valid date format" ); + return undef; + } + + +$CODE$ +LANGUAGE plperl; diff --git a/challenge-347/luca-ferrari/plperl/ch-2.plperl b/challenge-347/luca-ferrari/plperl/ch-2.plperl new file mode 100644 index 0000000000..0ca024bdf2 --- /dev/null +++ b/challenge-347/luca-ferrari/plperl/ch-2.plperl @@ -0,0 +1,39 @@ +-- +-- Perl Weekly Challenge 347 +-- Task 2 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +-- + +CREATE SCHEMA IF NOT EXISTS pwc347; + +CREATE OR REPLACE FUNCTION +pwc347.task2_plperl( text ) +RETURNS text +AS $CODE$ + + my ( $phone ) = @_; + + $phone =~ s/ [- ] //gx; + + my @groups; + while ( length( $phone ) >= 3 ) { + push @groups, join( '', ( ( split( //, $phone ) )[ 0 .. 2 ] ) ); + $phone =~ s/ ^ .{3} //xg; + } + + if ( $phone ) { + push @groups, $phone; + } + + if ( length( $groups[ $#groups ] ) != 2 || length( $groups[ $#groups ] ) != 3 ) { + my ( $end, $begin ) = ( pop @groups, pop @groups ); + my $last = $begin . $end; + push @groups, join( '', ( split( //, $last ) )[ 0 .. 1 ] ); + push @groups, join( '', ( split( //, $last ) )[ 2 .. 3 ] ); + } + + + return join( '-', @groups ); + +$CODE$ +LANGUAGE plperl; diff --git a/challenge-347/luca-ferrari/plpgsql/ch-1.sql b/challenge-347/luca-ferrari/plpgsql/ch-1.sql new file mode 100644 index 0000000000..e67a4442c4 --- /dev/null +++ b/challenge-347/luca-ferrari/plpgsql/ch-1.sql @@ -0,0 +1,49 @@ +-- +-- Perl Weekly Challenge 347 +-- Task 1 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +-- + +CREATE SCHEMA IF NOT EXISTS pwc347; + +CREATE OR REPLACE FUNCTION +pwc347.task1_plpgsql( d text ) +RETURNS date +AS $CODE$ +DECLARE + x text[]; + r text; + +BEGIN + CREATE TEMPORARY TABLE IF NOT EXISTS months( i int, m text ); + TRUNCATE TABLE months; + + INSERT INTO months( i, m ) + VALUES + ( 1, 'Jan' ) + , ( 2, 'Feb' ) + , ( 3, 'Mar' ) + , ( 4, 'Apr' ) + , ( 5, 'May' ) + , ( 6, 'Jun' ) + , ( 7, 'Jul' ) + , ( 8, 'Aug' ) + , ( 9, 'Sep' ) + , ( 10, 'Oct' ) + , ( 11, 'Nov' ) + , ( 12, 'Dec' ); + + r := ''; + x := regexp_matches( d, '(\d+).{2}\s+(\D{3})\s+(\d{4})' ); + + SELECT x[ 3 ] || '-' || m.i || '-' || x[ 1 ] + INTO r + FROM months m + WHERE m = x[ 2 ]; + + + RETURN r; + +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-347/luca-ferrari/plpgsql/ch-2.sql b/challenge-347/luca-ferrari/plpgsql/ch-2.sql new file mode 100644 index 0000000000..353663cfda --- /dev/null +++ b/challenge-347/luca-ferrari/plpgsql/ch-2.sql @@ -0,0 +1,60 @@ +-- +-- Perl Weekly Challenge 347 +-- Task 2 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +-- + +CREATE SCHEMA IF NOT EXISTS pwc347; + +CREATE OR REPLACE FUNCTION +pwc347.task2_plpgsql( phone text ) +RETURNS text +AS $CODE$ +DECLARE + x text; + r text; + i int; + + groups text[]; +BEGIN + + i := 0; + + + FOREACH x IN ARRAY regexp_split_to_array( phone, '' ) LOOP + + + IF x = '-' OR x = ' ' THEN + CONTINUE; + END IF; + + RAISE INFO 'x = %', x; + IF r IS NULL THEN + r := x; + ELSE + r := r || x; + END IF; + + i := i + 1; + + IF i = 3 THEN + groups := groups || r; + r := NULL; + i := 0; + END IF; + END LOOP; + + IF i <> 0 THEN + groups := groups || r; + END IF; + + IF length( groups[ array_length( groups, 1 ) ] ) THEN + RETURN pwc347.task2_plperl( phone ); + END IF; + + + RETURN array_to_string( groups, '-' ); + +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-347/luca-ferrari/python/ch-1.py b/challenge-347/luca-ferrari/python/ch-1.py new file mode 100644 index 0000000000..0457123160 --- /dev/null +++ b/challenge-347/luca-ferrari/python/ch-1.py @@ -0,0 +1,40 @@ +#!python + +# +# Perl Weekly Challenge 347 +# Task 1 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +# + +import sys +import re + +# task implementation +# the return value will be printed +def task_1( args ): + months = { 'Jan' : 1, + 'Feb' : 2, + 'Mar' : 3, + 'Apr' : 4, + 'May' : 5, + 'Jun' : 6, + 'Jul' : 7, + 'Aug' : 8, + 'Sep' : 9, + 'Oct' : 10, + 'Nov' : 11, + 'Dec' : 12 } + + + r = re.compile( r'\s+' ) + parts = r.split( args[ 0 ] ) + + return '-'.join( [ parts[ 2 ], + str( months[ parts[ 1 ] ] ), + parts[ 0 ].replace( 'st', '' ).replace( 'nd', '' ).replace( 'rd', '' ).replace( 'th', '' ) ] ) + + +# invoke the main without the command itself +if __name__ == '__main__': + print( task_1( sys.argv[ 1: ] ) ) diff --git a/challenge-347/luca-ferrari/python/ch-2.py b/challenge-347/luca-ferrari/python/ch-2.py new file mode 100644 index 0000000000..fab86b9763 --- /dev/null +++ b/challenge-347/luca-ferrari/python/ch-2.py @@ -0,0 +1,38 @@ +#!python + +# +# Perl Weekly Challenge 347 +# Task 2 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +# + +import sys + + +# task implementation +# the return value will be printed +def task_2( args ): + phone = args[ 0 ].replace( '-', '' ).replace( ' ', '' ) + + groups = [] + while len( phone ) > 0: + if len( phone ) >= 3: + groups.append( phone[ 0 : 3 ] ) + phone = phone[ 3: ] + else: + groups.append( phone ) + phone = '' + + if len( groups[ -1 ] ) != 2 and len( groups[ -1 ] ) != 3: + begin = groups[ -2 ] + end = groups[ -1 ] + last = begin + end + groups[ -2 ] = last[ 0 : 2 ] + groups[ -1 ] = last[ 2 : 4 ] + + return '-'.join( groups ) + +# invoke the main without the command itself +if __name__ == '__main__': + print( task_2( sys.argv[ 1: ] ) ) diff --git a/challenge-347/luca-ferrari/raku/ch-1.raku b/challenge-347/luca-ferrari/raku/ch-1.raku new file mode 100644 index 0000000000..02c6f2ca6d --- /dev/null +++ b/challenge-347/luca-ferrari/raku/ch-1.raku @@ -0,0 +1,28 @@ +#!raku + +# +# Perl Weekly Challenge 347 +# Task 1 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +# + +sub MAIN( Str $date ) { + my %months = 'Jan' => 1, + 'Feb' => 2, + 'Mar' => 3, + 'Apr' => 4, + 'May' => 5, + 'Jun' => 6, + 'Jul' => 7, + 'Aug' => 8, + 'Sep' => 9, + 'Oct' => 10, + 'Nov' => 11, + 'Dec' => 12; + + if ( $date ~~ / ^ $<day> = ( \d{1 .. 2} ) ( 'st' | 'nd' | 'rd' | 'th' ) \s+ $<month> = ( \w+ ) \s+ $<year> = ( \d+ ) $ / ) { + say '%04d-%02d-%02d'.sprintf: $/<year>, %months{ $/<month> }, $/<day>; + } + +} diff --git a/challenge-347/luca-ferrari/raku/ch-2.raku b/challenge-347/luca-ferrari/raku/ch-2.raku new file mode 100644 index 0000000000..617a58d299 --- /dev/null +++ b/challenge-347/luca-ferrari/raku/ch-2.raku @@ -0,0 +1,25 @@ +#!raku + +# +# Perl Weekly Challenge 347 +# Task 2 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-347> +# + +sub MAIN( Str $phone is copy ) { + $phone .= subst( / \s+ /, '', :g ); + $phone .= subst( / <[-]> /, '', :g ); + my @groups = $phone.comb( :skip-empty ).rotor( 3, :partial ); + @groups .= map( *.join ); + + if @groups[ * - 1 ].chars != 2|3 { + my $adjust = @groups[ * - 2 ] ~ @groups[ * - 1 ]; + @groups.pop; + @groups.pop; + @groups.push: |$adjust.comb.rotor( 2 ).map( *.join ); + } + + @groups.join( '-' ).say; + +} |
