diff options
| author | Paulo Custodio <pauloscustodio@gmail.com> | 2024-08-26 13:58:08 +0100 |
|---|---|---|
| committer | Paulo Custodio <pauloscustodio@gmail.com> | 2024-08-26 13:58:08 +0100 |
| commit | 707b0c338d30768c28e61631c27e2e29ccc75953 (patch) | |
| tree | f4d1f5122cbdb8fdc9bf0a5e25d859ce5030f34d | |
| parent | 7e7689b2bc6ea77f92d427c91e194caebe1d10a7 (diff) | |
| download | perlweeklychallenge-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/Makefile | 2 | ||||
| -rw-r--r-- | challenge-259/paulo-custodio/perl/ch-1.pl | 62 | ||||
| -rw-r--r-- | challenge-259/paulo-custodio/perl/ch-2.pl | 115 | ||||
| -rw-r--r-- | challenge-259/paulo-custodio/t/test-1.yaml | 10 | ||||
| -rw-r--r-- | challenge-259/paulo-custodio/t/test-2.yaml | 23 |
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", + |} |
