aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2024-08-26 13:58:08 +0100
committerPaulo Custodio <pauloscustodio@gmail.com>2024-08-26 13:58:08 +0100
commit707b0c338d30768c28e61631c27e2e29ccc75953 (patch)
treef4d1f5122cbdb8fdc9bf0a5e25d859ce5030f34d
parent7e7689b2bc6ea77f92d427c91e194caebe1d10a7 (diff)
downloadperlweeklychallenge-club-707b0c338d30768c28e61631c27e2e29ccc75953.tar.gz
perlweeklychallenge-club-707b0c338d30768c28e61631c27e2e29ccc75953.tar.bz2
perlweeklychallenge-club-707b0c338d30768c28e61631c27e2e29ccc75953.zip
Add Perl solution to challenge 259
-rw-r--r--challenge-259/paulo-custodio/Makefile2
-rw-r--r--challenge-259/paulo-custodio/perl/ch-1.pl62
-rw-r--r--challenge-259/paulo-custodio/perl/ch-2.pl115
-rw-r--r--challenge-259/paulo-custodio/t/test-1.yaml10
-rw-r--r--challenge-259/paulo-custodio/t/test-2.yaml23
5 files changed, 212 insertions, 0 deletions
diff --git a/challenge-259/paulo-custodio/Makefile b/challenge-259/paulo-custodio/Makefile
new file mode 100644
index 0000000000..c3c762d746
--- /dev/null
+++ b/challenge-259/paulo-custodio/Makefile
@@ -0,0 +1,2 @@
+all:
+ perl ../../challenge-001/paulo-custodio/test.pl
diff --git a/challenge-259/paulo-custodio/perl/ch-1.pl b/challenge-259/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..241df88e66
--- /dev/null
+++ b/challenge-259/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/env perl
+
+# Challenge 259
+#
+# Task 1: Banking Day Offset
+# Submitted by: Lee Johnson
+#
+# You are given a start date and offset counter. Optionally you also get bank
+# holiday date list.
+#
+# Given a number (of days) and a start date, return the number (of days)
+# adjusted to take into account non-banking days. In other words: convert a
+# banking day offset to a calendar day offset.
+#
+# Non-banking days are:
+#
+# a) Weekends
+# b) Bank holidays
+#
+# Example 1
+#
+# Input: $start_date = '2018-06-28', $offset = 3, $bank_holidays = ['2018-07-03']
+# Output: '2018-07-04'
+#
+# Thursday bumped to Wednesday (3 day offset, with Monday a bank holiday)
+#
+# Example 2
+#
+# Input: $start_date = '2018-06-28', $offset = 3
+# Output: '2018-07-03'
+
+use Modern::Perl;
+use DateTime;
+
+my $start_date = parse_date(shift @ARGV);
+my $offset = shift @ARGV;
+my @holidays;
+push @holidays, parse_date($_) for @ARGV;
+
+my $end_date = compute_offset($start_date, $offset, @holidays);
+say $end_date->ymd;
+
+sub compute_offset {
+ my($start_date, $offset, @holidays) = @_;
+ my %holidays; $holidays{$_}=1 for @holidays;
+
+ my $date = $start_date;
+ for (1 .. $offset) {
+ my $dow;
+ do {
+ $date->add(DateTime::Duration->new(days=>1));
+ $dow = $date->day_of_week;
+ } while ($dow==6 || $dow==7 || exists $holidays{$date});
+ }
+ return $date;
+}
+
+sub parse_date {
+ my($text) = @_;
+ my($year, $month, $day) = split /-/, $text;
+ return DateTime->new(year=>$year, month=>$month, day=>$day);
+}
diff --git a/challenge-259/paulo-custodio/perl/ch-2.pl b/challenge-259/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..46eafd3455
--- /dev/null
+++ b/challenge-259/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,115 @@
+#!/usr/bin/env perl
+
+# Challenge 259
+#
+# Task 2: Line Parser
+# Submitted by: Gabor Szabo
+#
+# You are given a line like below:
+#
+# {% id field1="value1" field2="value2" field3=42 %}
+#
+#
+# Where
+#
+# a) "id" can be \w+.
+# b) There can be 0 or more field-value pairs.
+# c) The name of the fields are \w+.
+# b) The values are either number in which case we don't need double quotes or
+# string in which case we need double quotes around them.
+#
+#
+# The line parser should return structure like below:
+#
+# {
+# name => id,
+# fields => {
+# field1 => value1,
+# field2 => value2,
+# field3 => value3,
+# }
+# }
+#
+#
+# It should be able to parse the following edge cases too:
+#
+# {% youtube title="Title \"quoted\" done" %}
+#
+#
+# and
+#
+# {% youtube title="Title with escaped backslash \\" %}
+#
+#
+# BONUS: Extend it to be able to handle multiline tags:
+#
+# {% id filed1="value1" ... %}
+# LINES
+# {% endid %}
+#
+#
+# You should expect the following structure from your line parser:
+#
+# {
+# name => id,
+# fields => {
+# field1 => value1,
+# field2 => value2,
+# field3 => value3,
+# }
+# text => LINES
+# }
+
+use Modern::Perl;
+use Parse::FSM::Lexer;
+use Data::Dump 'dump';
+
+my $text = "@ARGV";
+my $data = parse($text);
+say dump($data);
+
+sub parse {
+ my(@text) = @_;
+ my $data = {};
+
+ my $lex = Parse::FSM::Lexer->new;
+ $lex->from_list($text);
+
+ # start marker
+ (my $token = $lex->get_token()) or die "start marker missing";
+ $token->[0] eq "{" or die "start marker missing, got ", $token->[0];
+ ($token = $lex->get_token()) or die "start marker missing";
+ $token->[0] eq "%" or die "start marker missing, got ", $token->[0];
+
+ # name
+ ($token = $lex->get_token()) or die "name missing";
+ $token->[0] eq 'NAME' or die "name expected";
+ $data->{name} = $token->[1];
+
+ # fields
+ for (;;) {
+ # field name
+ ($token = $lex->get_token()) or die "field or end marker missing";
+ last if $token->[0] eq '%';
+ $token->[0] eq 'NAME' or die "field name expected, got ", $token->[0];
+ my $field_name = $token->[1];
+
+ # =
+ ($token = $lex->get_token()) or die "'=' expected";
+ $token->[0] eq '=' or die "'=' expected, got ", $token->[0];
+
+ # value
+ ($token = $lex->get_token()) or die "field value expected";
+ ($token->[0] eq 'NUM' || $token->[0] eq 'STR') or die "field value expected, got ", $token->[0];
+ my $field_value = $token->[1];
+
+ $data->{fields}{$field_name} = $field_value;
+ }
+
+ ($token = $lex->get_token()) or die "end marker missing";
+ $token->[0] eq '}' or die "end marker missing, got ", $token->[0];
+
+ defined($token = $lex->get_token()) and die "extra input, got ", $token->[0];
+
+ return $data;
+}
diff --git a/challenge-259/paulo-custodio/t/test-1.yaml b/challenge-259/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..e159d3fdc1
--- /dev/null
+++ b/challenge-259/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,10 @@
+- setup:
+ cleanup:
+ args: 2018-06-28 3 2018-07-03
+ input:
+ output: 2018-07-04
+- setup:
+ cleanup:
+ args: 2018-06-28 3
+ input:
+ output: 2018-07-03
diff --git a/challenge-259/paulo-custodio/t/test-2.yaml b/challenge-259/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..ac68f47087
--- /dev/null
+++ b/challenge-259/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,23 @@
+- setup:
+ cleanup:
+ args: '{% id field1=\"value1\" field2=\"value2\" field3=42 %}'
+ input:
+ output: |
+ |{
+ | fields => { field1 => "value1", field2 => "value2", field3 => 42 },
+ | name => "id",
+ |}
+- setup:
+ cleanup:
+ args: '{% youtube title=\"Title \\\"quoted\\\" done\" %}'
+ input:
+ output: { fields => { title => "Title \"quoted\" done" }, name => "youtube" }
+- setup:
+ cleanup:
+ args: '{% youtube title=\"Title with escaped backslash \\\\\" %}'
+ input:
+ output: |
+ |{
+ | fields => { title => "Title with escaped backslash \\" },
+ | name => "youtube",
+ |}