diff options
| author | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2024-03-04 17:24:02 +0000 |
|---|---|---|
| committer | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2024-03-04 17:24:02 +0000 |
| commit | 58d2a420a8de4551ea694c94ab1088cd795dad7d (patch) | |
| tree | d9ef49892910b3051d7c084c93fec202bcb6647e | |
| parent | 93e897d94b55160397eff52df0d0b59f1b00a861 (diff) | |
| parent | 074cecb5fed0a7961ba5c5f4b2605676fe589f25 (diff) | |
| download | perlweeklychallenge-club-58d2a420a8de4551ea694c94ab1088cd795dad7d.tar.gz perlweeklychallenge-club-58d2a420a8de4551ea694c94ab1088cd795dad7d.tar.bz2 perlweeklychallenge-club-58d2a420a8de4551ea694c94ab1088cd795dad7d.zip | |
Merge branch 'master' of https://github.com/manwar/perlweeklychallenge-club
35 files changed, 1766 insertions, 3 deletions
diff --git a/challenge-259/e-choroba/perl/ch-1.pl b/challenge-259/e-choroba/perl/ch-1.pl new file mode 100755 index 0000000000..ec52ff9e59 --- /dev/null +++ b/challenge-259/e-choroba/perl/ch-1.pl @@ -0,0 +1,155 @@ +#!/usr/bin/perl +use warnings; +use strict; +use experimental qw{ signatures }; + +use Time::Piece (); +use Time::Seconds qw( ONE_DAY ); + +use constant DATE_FORMAT => '%Y-%m-%d'; + +sub banking_day_offset($start, $offset, $holidays=[]) { + my %H; + @H{@$holidays} = (); + my $tp = 'Time::Piece'->strptime($start, DATE_FORMAT); + my $add = 0; + # Start date is weekend, move to Monday. + $add += $tp->wday % 5 if $tp->wday % 6 == 1; + + # How many weeks to move forward. + $add += 7 * int($offset / 5); + + # Remaining non-week days. + $add += $offset % 5; + + # Add a weekend if we went over it in the remaining non-week days. + $add += 2 if 1 != $tp->wday % 6 && $tp->wday + $offset % 5 > 6; + + my $date = $tp + ONE_DAY * $add; + + # Now handle the holidays. + for my $h (sort keys %H) { + my $holiday = 'Time::Piece'->strptime($h, DATE_FORMAT); + next if $holiday < $tp || $holiday->wday % 6 == 1; + if ($holiday <= $date) { + $date += ONE_DAY; + $date += 2 * ONE_DAY if $date->wday == 7; + } + } + + # We might still land on a weekend or holiday. + $date += ONE_DAY while $date->wday % 6 == 1 + || exists $H{ $date->strftime(DATE_FORMAT) }; + + return $date->strftime(DATE_FORMAT) +} + +sub banking_day_offset_slow($start, $offset, $holidays=[]) { + my %H; + @H{@$holidays} = (); + my $tp = 'Time::Piece'->strptime($start, DATE_FORMAT); + $tp += ONE_DAY while $tp->wday % 6 == 1 + || exists $H{ $tp->strftime(DATE_FORMAT) }; + for (1 .. $offset) { + $tp += ONE_DAY; + $tp += ONE_DAY while $tp->wday % 6 == 1 + || exists $H{ $tp->strftime(DATE_FORMAT) }; + } + return $tp->strftime(DATE_FORMAT) +} + +use Test::More tests => 2 + 1; + +my %DISPATCH = (slow => \&banking_day_offset_slow, + fast => \&banking_day_offset); + +for my $how (qw( slow fast )) { + my $banking_day_offset = $DISPATCH{$how}; + + subtest $how => sub { + is $banking_day_offset->('2018-06-28', 3, ['2018-07-03']), + '2018-07-04', + 'Example 1'; + + is $banking_day_offset->('2018-06-28', 3), + '2018-07-03', + 'Example 2'; + + is $banking_day_offset->('2018-06-28', 2, ['2018-07-02', '2018-07-03']), + '2018-07-04', + 'Land in the middle of holidays'; + + is $banking_day_offset->('2018-06-28', 2, ['2018-07-01', '2018-06-30']), + '2018-07-02', + 'Holidays on a weekend'; + + is $banking_day_offset->('2024-01-01', 262), + '2025-01-01', + 'Whole year'; + + is $banking_day_offset->('2018-06-28', 101, [qw[ 2018-11-16 2018-11-19]]), + '2018-11-20', + 'Holidays wrap a weekend'; + + is $banking_day_offset->('2012-05-22', 161, ['2012-05-22']), + '2013-01-03', + 'Start on a holiday'; + }, 2 + 5; +} + +use Benchmark qw{ cmpthese }; + +my $start = '2003-04-20'; +my $offset = 731; +my @h = qw[ 2001-10-08 2005-02-20 2000-01-07 2003-09-26 2000-08-14 + 2008-09-22 2003-05-10 2004-05-12 2004-10-12 2008-06-12 + 2003-06-15 2003-09-20 2006-08-01 2009-02-18 2006-07-11 + 2008-04-01 2003-10-03 2008-08-07 2008-11-17 2009-02-03 + 2004-08-18 2005-04-23 2003-08-15 2007-03-22 2004-11-07 + 2004-08-13 2008-09-04 2003-06-27 2006-07-12 2003-11-06 + 2000-01-30 2006-11-26 2004-07-05 2007-03-07 2000-12-11 + 2001-01-17 2007-01-18 2002-05-01 2000-01-06 2000-03-03 + 2005-09-05 2001-01-03 2005-06-02 2003-08-15 2002-09-13 + 2006-07-15 2005-06-22 2001-10-27 2005-07-14 2004-09-19 + 2008-02-10 2003-05-10 2007-08-11 2000-02-05 2002-01-25 + 2002-03-28 2003-07-26 2007-08-13 2002-03-21 2003-03-09 + 2006-03-11 2004-03-05 2004-05-08 2006-09-24 2000-10-03 + 2001-12-19 2003-02-26 2005-10-06 2001-08-23 2004-09-25 + 2009-12-20 2004-10-10 2005-08-15 2001-11-25 2002-03-11 + 2007-10-22 2000-10-30 2009-04-14 2009-10-30 2004-09-01 + 2004-04-11 2000-04-04 2003-11-14 2004-11-16 2001-06-28 + 2008-11-18 2009-11-16 2006-01-27 2007-08-06 2009-09-14 + 2000-10-25 2001-09-14 2000-09-17 2007-01-07 2005-02-05 + 2000-09-20 2002-02-01 2003-05-08 2002-06-03 2006-12-02 + 2009-08-15 2008-11-22 2002-12-23 2002-06-08 2003-09-27 + 2004-10-08 2007-12-16 2005-12-19 2003-05-15 2007-10-30 + 2006-11-13 2005-12-04 2006-09-06 2005-05-08 2007-10-23 + 2006-05-31 2005-01-16 2009-02-15 2000-05-08 2002-04-13 + 2000-07-11 2005-05-25 2004-07-03 2007-12-03 2008-07-19 + 2009-08-27 2004-08-27 2002-03-14 2007-03-29 2005-02-03 + 2004-10-30 2000-07-14 2004-01-27 2004-12-18 2004-12-08 + 2005-11-23 2008-04-18 2000-03-06 2009-05-31 2002-08-13 + 2000-12-25 2008-09-17 2004-06-10 2003-04-29 2003-04-28 + 2000-04-30 2005-04-18 2003-08-01 2000-05-22 2009-03-18 + 2002-08-08 2008-11-15 2006-03-17 2003-07-17 2006-10-02 + 2007-01-17 2009-09-04 2000-04-22 2007-04-23 2006-01-08 + 2003-08-01 2003-08-11 2003-02-10 2007-04-08 2003-02-26 + 2002-05-16 2002-11-04 2004-01-07 2001-09-28 2001-11-29 + 2002-03-19 2009-10-08 2002-08-25 2004-08-22 2003-06-23 + 2001-05-23 2000-12-02 2000-04-26 2000-05-25 2006-05-15 + 2006-08-18 2009-12-26 2008-07-31 2009-10-02 2002-07-19 + 2006-08-01 2000-06-09 2006-04-10 ]; + +is banking_day_offset($start, $offset, [@h]), + banking_day_offset_slow($start, $offset, [@h]), + 'long'; + +cmpthese(-3, { + slow => sub { banking_day_offset_slow($start, $offset, [@h]) }, + fast => sub { banking_day_offset($start, $offset, [@h]) }, +}) + +__END__ + Rate slow fast +slow 84.1/s -- -80% +fast 431/s 412% -- diff --git a/challenge-259/e-choroba/perl/ch-2.pl b/challenge-259/e-choroba/perl/ch-2.pl new file mode 100755 index 0000000000..cb76a4af8f --- /dev/null +++ b/challenge-259/e-choroba/perl/ch-2.pl @@ -0,0 +1,109 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use Marpa::R2 (); + +my $dsl = << '__DSL__'; +lexeme default = latm => 1 +:default ::= action => ::first + +BonusStruct ::= Struct + | Struct (nl) Lines (End) action => bonus +End ::= (begin ws) (Endid) (ws end) action => [] +Endid ::= ('end') Id action => check_id +Struct ::= (begin) (ws) Id (ws) Fields (ws) (end) action => struct +Id ::= word +Lines ::= char Lines action => concat + | char +Fields ::= Field (ws) Fields action => merge + | Field +Field ::= Name (eq) Value action => name_val +Name ::= word +Value ::= Number + | (qq) Quoted (qq) +Number ::= digit + | nonz Digits action => concat +Digits ::= digit Digits action => concat + | digit +Quoted ::= Char Quoted action => concat + | Char +Char ::= bs action => bs + | dq action => dq + || char + +begin ~ '{%' +end ~ '%}' +qq ~ '"' +word ~ [\w]+ +bs ~ '\\' +dq ~ '\"' +char ~ [\s\S] +eq ~ '=' +digit ~ [0-9] +nonz ~ [1-9] +ws ~ [\s]+ +nl ~ [\n] +__DSL__ + +sub concat { $_[1] . $_[2] } +sub name_val { +{$_[1] => $_[2]} } +sub merge { +{%{ $_[1] }, %{ $_[2] }} } +sub struct { $_[0] = $_[1]; {name => $_[1], fields => $_[2]} } +sub bonus { +{%{ $_[1] }, text => $_[2]} } +sub check_id { $_[0] eq $_[1] or die "Invalid id" } +sub bs { '\\' } +sub dq { '"' } + +my $grammar = 'Marpa::R2::Scanless::G'->new({source => \$dsl}); +use experimental qw{ signatures }; +sub line_parser($input) { + my $value_ref = $grammar->parse(\$input, 'main'); + return $$value_ref +} + +use Test2::V0; +plan 5; + +is line_parser('{% id field1="value1" field2="value2" field3=42 %}'), + { + name => 'id', + fields => { + field1 => 'value1', + field2 => 'value2', + field3 => 42, + } + }, 'Example 1'; + +is line_parser('{% youtube title="Title \"quoted\" done" %}'), + { name => 'youtube', fields => {title => 'Title "quoted" done'}}, + 'Double quotes'; + +is line_parser('{% youtube title="Title with escaped backslash \\\\" %}'), + { + name => 'youtube', + fields => { + title => 'Title with escaped backslash \\' + } + }, + 'Backslash'; + +is line_parser('{% id filed1="value1" %} +LINES +{% endid %}'), + { + name => 'id', + fields => { + filed1 => 'value1' + }, + text => "LINES\n" + }, + 'bonus'; + +my $e = dies { + line_parser(join "\n", + '{% id filed1="value1" %}', + 'LINES', + '{% endOTHERID %}' + ) }; +like $e, qr/Invalid id/, 'Fails'; diff --git a/challenge-259/luca-ferrari/blog-1.txt b/challenge-259/luca-ferrari/blog-1.txt new file mode 100644 index 0000000000..f59eee9b34 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-1.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task1 diff --git a/challenge-259/luca-ferrari/blog-10.txt b/challenge-259/luca-ferrari/blog-10.txt new file mode 100644 index 0000000000..3a8f05e0f8 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-10.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/[= date -%]/PerlWeeklyChallenge259.html#task2pljava diff --git a/challenge-259/luca-ferrari/blog-2.txt b/challenge-259/luca-ferrari/blog-2.txt new file mode 100644 index 0000000000..9fa1af6ea8 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-2.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task2 diff --git a/challenge-259/luca-ferrari/blog-3.txt b/challenge-259/luca-ferrari/blog-3.txt new file mode 100644 index 0000000000..26ad2f3825 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-3.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task1plperl diff --git a/challenge-259/luca-ferrari/blog-4.txt b/challenge-259/luca-ferrari/blog-4.txt new file mode 100644 index 0000000000..a1c1a8df1d --- /dev/null +++ b/challenge-259/luca-ferrari/blog-4.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task2plperl diff --git a/challenge-259/luca-ferrari/blog-5.txt b/challenge-259/luca-ferrari/blog-5.txt new file mode 100644 index 0000000000..8f99d56a78 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-5.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task1plpgsql diff --git a/challenge-259/luca-ferrari/blog-6.txt b/challenge-259/luca-ferrari/blog-6.txt new file mode 100644 index 0000000000..2956e4b204 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-6.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task2plpgsql diff --git a/challenge-259/luca-ferrari/blog-7.txt b/challenge-259/luca-ferrari/blog-7.txt new file mode 100644 index 0000000000..ae78544493 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-7.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task1python diff --git a/challenge-259/luca-ferrari/blog-8.txt b/challenge-259/luca-ferrari/blog-8.txt new file mode 100644 index 0000000000..0374c2d0a7 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-8.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task2python diff --git a/challenge-259/luca-ferrari/blog-9.txt b/challenge-259/luca-ferrari/blog-9.txt new file mode 100644 index 0000000000..7521039415 --- /dev/null +++ b/challenge-259/luca-ferrari/blog-9.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2024/03/04/PerlWeeklyChallenge259.html#task1pljava diff --git a/challenge-259/luca-ferrari/pljava/pom.xml b/challenge-259/luca-ferrari/pljava/pom.xml index 1a0d8dbf4d..30b7a337f3 100644 --- a/challenge-259/luca-ferrari/pljava/pom.xml +++ b/challenge-259/luca-ferrari/pljava/pom.xml @@ -5,11 +5,11 @@ <modelVersion>4.0.0</modelVersion> <groupId>PWC</groupId> - <artifactId>PWC258</artifactId> + <artifactId>PWC259</artifactId> <version>1</version> - <name>Perl Weekly Challenge 258</name> - <description>Implementation of the tasks in PL/Java for PWC 258</description> + <name>Perl Weekly Challenge 259</name> + <description>Implementation of the tasks in PL/Java for PWC 259</description> <properties> <project.build.sourceEncoding>US-ASCII</project.build.sourceEncoding> diff --git a/challenge-259/luca-ferrari/pljava/src/main/java/Task1.java b/challenge-259/luca-ferrari/pljava/src/main/java/Task1.java new file mode 100644 index 0000000000..de464e56c0 --- /dev/null +++ b/challenge-259/luca-ferrari/pljava/src/main/java/Task1.java @@ -0,0 +1,73 @@ + + + +package PWC259; + +/** + * PL/Java implementation for PWC 259 + * Task 1 + * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> + * + * + * 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/PWC259-1.jar luca@rachel:/tmp + + + * To install into PostgreSQL execute: + + select sqlj.install_jar( 'file:///tmp/PWC259-1.jar', 'PWC259', true ); + + select pwc259.task2_pljava(); + + and then to redeploy: + + select sqlj.replace_jar( 'file:///tmp/PWC259-1.jar', 'PWC259', 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 = "pwc259", + onNullInput = RETURNS_NULL, + effects = IMMUTABLE ) + public static final java.sql.Date task1_pljava( Date startDay, int how_many, Date[] holidays ) throws SQLException { + logger.log( Level.INFO, "Entering pwc259.task1_pljava" ); + + Calendar day = Calendar.getInstance(); + day.setTime( startDay ); + + while ( how_many > 0 ) { + day.add( Calendar.DAY_OF_YEAR, 1 ); + + while ( day.get( Calendar.DAY_OF_MONTH ) == Calendar.SUNDAY + || day.get( Calendar.DAY_OF_MONTH ) == Calendar.SATURDAY ) + day.add( Calendar.DAY_OF_YEAR, 1 ); + + if ( holidays != null ) + for ( Date skip : holidays ) + if ( skip.equals( day.getTime() ) ) + day.add( Calendar.DAY_OF_YEAR, 1 ); + + how_many--; + } + + return new java.sql.Date( day.getTimeInMillis() ); + } +} diff --git a/challenge-259/luca-ferrari/pljava/src/main/java/Task2.java b/challenge-259/luca-ferrari/pljava/src/main/java/Task2.java new file mode 100644 index 0000000000..1a33f13bea --- /dev/null +++ b/challenge-259/luca-ferrari/pljava/src/main/java/Task2.java @@ -0,0 +1,107 @@ + + + +package PWC259; + +/** + * PL/Java implementation for PWC 259 + * Task 2 + * See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> + * + * + * 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/PWC259-1.jar luca@rachel:/tmp + + + * To install into PostgreSQL execute: + + select sqlj.install_jar( 'file:///tmp/PWC259-1.jar', 'PWC259', true ); + + select pwc259.task2_pljava(); + + and then to redeploy: + + select sqlj.replace_jar( 'file:///tmp/PWC259-1.jar', 'PWC259', 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.regex.*; +import java.util.stream.*; +import java.sql.SQLException; +import java.util.logging.*; +import java.sql.ResultSet; +import java.sql.Date; + +public class Task2 implements ResultSetProvider { + + private final static Logger logger = Logger.getAnonymousLogger(); + + @Function( schema = "pwc259", + onNullInput = RETURNS_NULL, + effects = IMMUTABLE ) + public static final ResultSetProvider task2_pljava( String line ) throws SQLException { + logger.log( Level.INFO, "Entering pwc259.task2_pljava : " + line ); + return new Task2( line ); + } + + + public Task2( String line ) throws SQLException { + params = new LinkedList< List<String> >(); + parse( line ); + } + + + private final void parse( String line ) throws SQLException { + Pattern pattern = Pattern.compile( "[{][%] (\\w+)\\s*(.*)\\s* [%][}]" ); + Matcher matcher = pattern.matcher( line ); + + if ( matcher.find() ) { + id = matcher.group( 1 ); + + Pattern subPattern = Pattern.compile( "(\\w+)[=](\\w+)\\s*" ); + Matcher subMatch = subPattern.matcher( matcher.group( 2 ) ); + + while ( subMatch.find() ) { + List<String> current = new LinkedList<String>(); + current.add( subMatch.group( 1 ) ); + current.add( subMatch.group( 2 ) ); + params.add( current ); + + } + } + else + throw new SQLException( "Cannot parse " + line ); + + } + + private List< List<String> > params; + private String id; + + @Override + public boolean assignRowValues(ResultSet rs, int row) + throws SQLException { + + // stop the result set + if ( row >= params.size() ) + return false; + + rs.updateInt( 1, row ); + rs.updateString( 2, id ); + rs.updateString( 3, params.get( row ).get( 0 ) ); + rs.updateString( 4, params.get( row ).get( 1 ) ); + return true; + } + + @Override + public void close() { + } +} diff --git a/challenge-259/luca-ferrari/plperl/ch-1.plperl b/challenge-259/luca-ferrari/plperl/ch-1.plperl new file mode 100644 index 0000000000..bd7a6e6a27 --- /dev/null +++ b/challenge-259/luca-ferrari/plperl/ch-1.plperl @@ -0,0 +1,41 @@ +-- +-- Perl Weekly Challenge 259 +-- Task 1 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> +-- + +CREATE SCHEMA IF NOT EXISTS pwc259; + +CREATE OR REPLACE FUNCTION +pwc259.task1_plperl( date, int, date[] ) +RETURNS date +AS $CODE$ + +use DateTime; + + my ( $when, $offset, $holidays ) = @_; + + $when =~ / ^ (?<year>\d{4}) [-] (?<month>\d{2}) [-] (?<day>\d{2}) $ /x; + + my $day = DateTime->new( year => $+{ year}, month => $+{ month }, day => $+{ day } ); + + while ( $offset > 0 ) { + $day->add( days => 1 ); + $offset--; + + # skip weekends + while ( $day->day_of_week == 6 || $day->day_of_week == 7 ) { + $day->add( days => 1 ); + } + + if ( $holidays->@* ) { + while( grep { $_ eq $day->ymd } $holidays->@* ) { + $day->add( days => 1 ); + } + } + } + + return $day->ymd; + +$CODE$ +LANGUAGE plperlu; diff --git a/challenge-259/luca-ferrari/plperl/ch-2.plperl b/challenge-259/luca-ferrari/plperl/ch-2.plperl new file mode 100644 index 0000000000..b3500be853 --- /dev/null +++ b/challenge-259/luca-ferrari/plperl/ch-2.plperl @@ -0,0 +1,58 @@ +-- +-- Perl Weekly Challenge 259 +-- Task 2 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> +-- + +CREATE SCHEMA IF NOT EXISTS pwc259; + +CREATE OR REPLACE FUNCTION +pwc259.task2_plperl( text) +RETURNS TABLE( id text, field_name text, field_value text ) +AS $CODE$ + + my ( $line ) = @_; + + if ( $line =~ / ^ [{] [%] \s* (?<id>\w+) \s* (?<options>.*) \s* [%] [}] $ /x ) { + my $id = $+{ id }; + my ( $name, $value ) = ( '', '' ); + if ( $+{ options } ) { + my $is_value = 0; + my $allowed_spaces = 0; + my $previous = ''; + + for ( split //, $+{ options } ) { + + + $is_value = 1 and $previous = $_ and next if ( $_ eq '=' ); + $allowed_spaces = 1 and $previous = $_ and next if ( $_ eq '"' and $previous eq '=' ); + + $name .= $_ if ( ! $is_value ); + $value .= $_ if ( $is_value ); + + if ( $is_value + && ( ( $_ eq ' ' && ! $allowed_spaces ) + || ( $_ eq '"' && $previous ne '\\' && $allowed_spaces ) ) + ) { + # stop here! + $value =~ s/^\s*|\s*$//g; + $value =~ s/^["]|["]$//g; + $value =~ s/\\"/"/g; + return_next( { id => $id , + field_name => $name, + field_value => $value } ); + + ( $name, $value, $is_value, $allowed_spaces ) = ( '', '', 0, 0 ); + } + + $previous = $_; + } + + + } + } + + return undef; + +$CODE$ +LANGUAGE plperl; diff --git a/challenge-259/luca-ferrari/plpgsql/ch-1.sql b/challenge-259/luca-ferrari/plpgsql/ch-1.sql new file mode 100644 index 0000000000..4b8f2eff5a --- /dev/null +++ b/challenge-259/luca-ferrari/plpgsql/ch-1.sql @@ -0,0 +1,36 @@ +-- +-- Perl Weekly Challenge 259 +-- Task 1 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> +-- + +CREATE SCHEMA IF NOT EXISTS pwc259; + +CREATE OR REPLACE FUNCTION +pwc259.task1_plpgsql( day date, how_many_days int, holidays date[] ) +RETURNS date +AS $CODE$ +DECLARE + current_holiday date; +BEGIN + + WHILE how_many_days > 0 LOOP + day := day + 1; + + WHILE extract( dow from day ) IN ( 0, 6 ) LOOP + day := day + 1; + END LOOP; + + FOREACH current_holiday IN ARRAY holidays LOOP + IF current_holiday = day THEN + day := day + 1; + END IF; + END LOOP; + + how_many_days := how_many_days - 1; + END LOOP; + + RETURN day; +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-259/luca-ferrari/plpgsql/ch-2.sql b/challenge-259/luca-ferrari/plpgsql/ch-2.sql new file mode 100644 index 0000000000..15c2f30024 --- /dev/null +++ b/challenge-259/luca-ferrari/plpgsql/ch-2.sql @@ -0,0 +1,15 @@ +-- +-- Perl Weekly Challenge 259 +-- Task 2 +-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> +-- + +CREATE SCHEMA IF NOT EXISTS pwc259; + +CREATE OR REPLACE FUNCTION +pwc259.task2_plpgsql( line text ) +RETURNS TABLE( id text, field_name text, field_value text ) +AS $CODE$ + SELECT pwc259.task2_plperl( line ); +$CODE$ +LANGUAGE sql; diff --git a/challenge-259/luca-ferrari/python/ch-1.py b/challenge-259/luca-ferrari/python/ch-1.py new file mode 100644 index 0000000000..9b3a0fd121 --- /dev/null +++ b/challenge-259/luca-ferrari/python/ch-1.py @@ -0,0 +1,37 @@ +#!python + +# +# Perl Weekly Challenge 259 +# Task 1 +# +# See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-259> +# + +import sys +from datetime import date, timedelta + +# task implementation +# the return value will be printed +def task_1( args ): + day = date.fromisoformat( args[ 0 ] ) + offset = int( args[ 1 ] ) + holidays = list( map( lambda x: date.fromisoformat( x ), args[ 2: ] ) ) + one_day = timedelta( days=1 ) + |
