aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaldhar H. Vyas <jaldhar@braincells.com>2025-10-02 21:11:27 -0400
committerJaldhar H. Vyas <jaldhar@braincells.com>2025-10-03 01:25:38 -0400
commit65553335d966040f75e951ef1223636876da5e03 (patch)
treeb12ffa49ce2797cbb9cfbf1559c9618c0be5ad4d
parent5991138e306a72597a1609d1cc2e41da6369c93a (diff)
downloadperlweeklychallenge-club-65553335d966040f75e951ef1223636876da5e03.tar.gz
perlweeklychallenge-club-65553335d966040f75e951ef1223636876da5e03.tar.bz2
perlweeklychallenge-club-65553335d966040f75e951ef1223636876da5e03.zip
Challenge 259 by Jaldhar H. Vyas.
-rwxr-xr-xchallenge-259/jaldhar-h-vyas/perl/ch-1.pl25
-rwxr-xr-xchallenge-259/jaldhar-h-vyas/perl/ch-2.pl60
-rwxr-xr-xchallenge-259/jaldhar-h-vyas/raku/ch-1.raku21
-rwxr-xr-xchallenge-259/jaldhar-h-vyas/raku/ch-2.raku105
4 files changed, 211 insertions, 0 deletions
diff --git a/challenge-259/jaldhar-h-vyas/perl/ch-1.pl b/challenge-259/jaldhar-h-vyas/perl/ch-1.pl
new file mode 100755
index 0000000000..1cda735ecd
--- /dev/null
+++ b/challenge-259/jaldhar-h-vyas/perl/ch-1.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+use 5.038;
+use warnings;
+use DateTime;
+use DateTime::Format::Strptime;
+
+my $strptime = DateTime::Format::Strptime->new(
+ pattern => '%F',
+ on_error => sub { die "Invalid date\n"; }
+);
+
+my $startDate = $strptime->parse_datetime(shift @ARGV);
+my $offset = shift @ARGV;
+my @bankHolidays = map { $strptime->parse_datetime($_) } @ARGV;
+my $endDate = $startDate;
+
+while ($offset > 0 ) {
+ $endDate->add(days => 1);
+ my $dow = $endDate->dow;
+ if ($dow > 0 && $dow < 6 && !grep { $_ == $endDate } @bankHolidays) {
+ $offset--;
+ }
+}
+
+say $endDate->ymd;
diff --git a/challenge-259/jaldhar-h-vyas/perl/ch-2.pl b/challenge-259/jaldhar-h-vyas/perl/ch-2.pl
new file mode 100755
index 0000000000..2c9ac89821
--- /dev/null
+++ b/challenge-259/jaldhar-h-vyas/perl/ch-2.pl
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+use 5.038;
+use warnings;
+use Parse::RecDescent;
+
+# $::RD_TRACE = 1;
+
+my $grammar = <<'-EOT-';
+ startrule: multi_line | single_line
+
+ single_line: '{%' ws identifier field(s) '%}'
+ {
+ $return = "{\n"
+ . " name => $item{identifier},\n"
+ . " fields => {\n "
+ . join(",\n ", @{$item{'field(s)'}})
+ . "\n }\n"
+ . "}\n";
+ }
+
+ multi_line: '{%' ws identifier field(s) '%}' text '{%' ws "endmyid" ws '%}'
+ {
+ $return = "{\n"
+ . " name => $item{identifier},\n"
+ . " fields => {\n "
+ . join(",\n ", @{$item{'field(s)'}})
+ . "\n },\n"
+ . " text => $item{text}"
+ . "}\n";
+ }
+
+ ws: /\s*/
+
+ identifier: /\w+/
+ {
+ my $id = $item[1];
+ $return = $id;
+ }
+
+ field: ws name ws '=' ws value
+ { $return = "$item{ name } => $item{ value }" }
+
+ name: /\w+/
+
+ value: number | string
+
+ number: /\d+/
+ { $return = 0 + $item[1]; }
+
+ string: /"/ content /"/
+ { $return = $item{content}; }
+
+ content: /(\\" | \\\\ | [^"])+/x
+
+ text: /[^{]+/
+-EOT-
+
+my $parser = Parse::RecDescent->new($grammar);
+my $text = shift;
+say $parser->startrule($text);
diff --git a/challenge-259/jaldhar-h-vyas/raku/ch-1.raku b/challenge-259/jaldhar-h-vyas/raku/ch-1.raku
new file mode 100755
index 0000000000..742adcac7b
--- /dev/null
+++ b/challenge-259/jaldhar-h-vyas/raku/ch-1.raku
@@ -0,0 +1,21 @@
+#!/usr/bin/raku
+
+sub MAIN(
+ $start,
+ $offset is copy,
+ *@holidays
+) {
+ my $startDate = Date.new($start);
+ my @bankHolidays = @holidays.map({ Date.new($_) });
+ my $endDate = $startDate;
+
+ while ($offset > 0 ) {
+ $endDate += 1;
+ my $dow = $endDate.day-of-week;
+ if ($dow > 0 && $dow < 6 && @bankHolidays.none == $endDate) {
+ $offset--;
+ }
+ }
+
+ say $endDate.yyyy-mm-dd;
+} \ No newline at end of file
diff --git a/challenge-259/jaldhar-h-vyas/raku/ch-2.raku b/challenge-259/jaldhar-h-vyas/raku/ch-2.raku
new file mode 100755
index 0000000000..8f3ab62275
--- /dev/null
+++ b/challenge-259/jaldhar-h-vyas/raku/ch-2.raku
@@ -0,0 +1,105 @@
+#!/usr/bin/raku
+
+grammar LineParser {
+ rule TOP {
+ | <single-line>
+ | <multi-line>
+ }
+
+ token single-line {
+ ^ '{%' \s+ <identifier> <field>* \s* '%}' $
+ }
+
+ token multi-line {
+ '{%' \s+ <identifier> <field>* \s* '%}' \n
+ <text>
+ '{%' \s+ 'end' <end-id=.identifier> \s* '%}' \n?
+ }
+
+ token identifier { \w+ }
+
+ token ws { \h* }
+
+ token field {
+ \s+ <name=.identifier> \s* '=' \s* <value>
+ }
+
+ proto token value {*}
+
+ token value:sym<number> { \d+ }
+
+ token value:sym<string> {
+ '"' <content> '"'
+ }
+
+ token content {
+ [
+ | <-[\"\\]>+
+ | '\\"'
+ | '\\\\'
+ ]*
+ }
+
+ token text {
+ <-[{]>*
+ }
+}
+
+class LineActions {
+ method TOP($/) {
+ make $<single-line> ?? $<single-line>.made !! $<multi-line>.made;
+ }
+
+ method single-line($/) {
+ make {
+ name => ~$<identifier>,
+ fields => $<field>.map({
+ ~$_<name> => $_<value>.made
+ }).Hash
+ }
+ }
+
+ method multi-line($/) {
+ die "Closing tag 'end{$<identifier>}' does not match opening tag '{$<end-id>}'"
+ unless $<identifier> eq $<end-id>;
+
+ make {
+ name => ~$<identifier>,
+ fields => $<field>.map({
+ ~$_<name> => $_<value>.made
+ }).Hash,
+ text => ~$<text>
+ }
+ }
+
+ method value:sym<number>($/) { make +$/ }
+ method value:sym<string>($/) {
+ make ~$<content>
+ .subst(/'\\"'/, '"', :g)
+ .subst(/'\\\\'/, '\\', :g)
+ }
+}
+
+sub prettyprint(%data) {
+ my $output = "\{\n name => %data<name>,\n fields => \{\n ";
+
+ $output ~= %data<fields>
+ .keys
+ .map({ "$_ => %data<fields>{$_}" })
+ .join(",\n ");
+
+
+ $output ~= "\n \},\n";
+ if %data<text> {
+ $output ~= " text => %data<text>";
+ }
+ $output ~= "}\n";
+
+ return $output;
+}
+
+sub MAIN($input) {
+ my $actions = LineActions.new;
+ my $match = LineParser.parse($input, :$actions);
+ say $match ?? prettyprint($match.made) !! 'Failed to parse line';
+} \ No newline at end of file