aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2025-06-21 23:02:45 +1000
committerPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2025-06-21 23:02:45 +1000
commited95f6c8290d5ca5d0569161038ce2da0a74ff31 (patch)
tree3482cb3886d32ad28341997e3e5f5a57b412ad42
parent34d68e3f51f7f20b11144e317da434662ab66191 (diff)
downloadperlweeklychallenge-club-ed95f6c8290d5ca5d0569161038ce2da0a74ff31.tar.gz
perlweeklychallenge-club-ed95f6c8290d5ca5d0569161038ce2da0a74ff31.tar.bz2
perlweeklychallenge-club-ed95f6c8290d5ca5d0569161038ce2da0a74ff31.zip
Perl & Raku solutions to Tasks 1 & 2 for Week 326
-rw-r--r--challenge-326/athanasius/perl/ch-1.pl172
-rw-r--r--challenge-326/athanasius/perl/ch-2.pl179
-rw-r--r--challenge-326/athanasius/raku/ch-1.raku159
-rw-r--r--challenge-326/athanasius/raku/ch-2.raku167
4 files changed, 677 insertions, 0 deletions
diff --git a/challenge-326/athanasius/perl/ch-1.pl b/challenge-326/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..7928a62ae2
--- /dev/null
+++ b/challenge-326/athanasius/perl/ch-1.pl
@@ -0,0 +1,172 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 326
+=========================
+
+TASK #1
+-------
+*Day of the Year*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a date in the format YYYY-MM-DD.
+
+Write a script to find day number of the year that the given date represent.
+
+Example 1
+
+ Input: $date = '2025-02-02'
+ Output: 33
+
+ The 2nd Feb, 2025 is the 33rd day of the year.
+
+Example 2
+
+ Input: $date = '2025-04-10'
+ Output: 100
+
+Example 3
+
+ Input: $date = '2025-09-07'
+ Output: 250
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A valid date in the format "YYYY-MM-DD" is entered on the command-line.
+
+=cut
+#===============================================================================
+
+use v5.32; # Enables strictures
+use warnings;
+use Const::Fast;
+use DateTime;
+use Syntax::Keyword::Try;
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 <date>
+ perl $0
+
+ <date> A valid date in the format "YYYY-MM-DD"
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 326, Task #1: Day of the Year (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $argc = scalar @ARGV;
+
+ if ($argc == 0)
+ {
+ run_tests();
+ }
+ elsif ($argc == 1)
+ {
+ my $date = $ARGV[ 0 ];
+
+ print "Input: \$date = '$date'\n";
+
+ my $day_of_year = find_day_of_year( $date );
+
+ print "Output: $day_of_year\n";
+ }
+ else
+ {
+ error( "Expected 1 or 0 command-line arguments, found $argc" );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_day_of_year
+#-------------------------------------------------------------------------------
+{
+ my ($date) = @_;
+ $date =~ / ^ (\d{4}) - (\d\d) - (\d\d) $ /x
+ or error( 'Invalid date format' );
+
+ my ($year, $month, $day) = ($1, $2, $3);
+
+ 0 < $month <= 12 or error( qq[Invalid month "$month"] );
+ 0 < $day <= 31 or error( qq[Invalid day "$day"] );
+
+ my $dt;
+
+ try
+ {
+ $dt = DateTime->new( year => $year, month => $month, day => $day );
+ }
+ catch
+ {
+ my $msg = $@ =~ s/ (\n .*) $ //rx;
+ chomp $msg;
+ error( $msg );
+ }
+
+ return $dt->day_of_year;
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $date, $expected) = split / \| /x, $line;
+
+ for ($test_name, $date, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my $day_of_year = find_day_of_year( $date );
+
+ is $day_of_year, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|2025-02-02| 33
+Example 2|2025-04-10|100
+Example 3|2025-09-07|250
diff --git a/challenge-326/athanasius/perl/ch-2.pl b/challenge-326/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..df3461bc77
--- /dev/null
+++ b/challenge-326/athanasius/perl/ch-2.pl
@@ -0,0 +1,179 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 326
+=========================
+
+TASK #2
+-------
+*Decompressed List*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers having even elements.
+
+Write a script to return the decompress[ed] list. To decompress, pick adjacent
+pair (i, j) and replace it with j, i times.
+
+Example 1
+
+ Input: @ints = (1, 3, 2, 4)
+ Output: (3, 4, 4)
+
+ Pair 1: (1, 3) => 3 one time => (3)
+ Pair 2: (2, 4) => 4 two times => (4, 4)
+
+Example 2
+
+ Input: @ints = (1, 1, 2, 2)
+ Output: (1, 2, 2)
+
+ Pair 1: (1, 1) => 1 one time => (1)
+ Pair 2: (2, 2) => 2 two times => (2, 2)
+
+Example 3
+
+ Input: @ints = (3, 1, 3, 2)
+ Output: (1, 1, 1, 2, 2, 2)
+
+ Pair 1: (3, 1) => 1 three times => (1, 1, 1)
+ Pair 2: (3, 2) => 2 three times => (2, 2, 2)
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Assumption
+----------
+"Positive" integers are greater than zero.
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A non-empty, even-sized list of positive integers is entered on the command-
+ line.
+
+=cut
+#===============================================================================
+
+use v5.32; # Enables strictures
+use warnings;
+use Const::Fast;
+use List::Util qw( pairs );
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 [<ints> ...]
+ perl $0
+
+ [<ints> ...] A non-empty, even-sized list of positive integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 326, Task #2: Decompressed List (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $argc = scalar @ARGV;
+
+ if ($argc == 0)
+ {
+ run_tests();
+ }
+ elsif ($argc % 2 == 0)
+ {
+ my @ints = @ARGV;
+
+ for (@ints)
+ {
+ / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] );
+ $_ > 0 or error( "$_ is not positive" );
+ }
+
+ printf "Input: \@ints = (%s)\n", join ', ', @ints;
+
+ my $decompressed = decompress( \@ints );
+
+ printf "Output: (%s)\n", join ', ', @$decompressed;
+ }
+ else
+ {
+ error( 'The input list is not even in size' );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub decompress
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my @decompressed;
+
+ for my $pair (pairs @$ints)
+ {
+ push @decompressed, ($pair->value) x $pair->key;
+ }
+
+ return \@decompressed;
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $ints_str, $expected_str) = split / \| /x, $line;
+
+ for ($test_name, $ints_str, $expected_str)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints_str;
+ my $decompressed = decompress( \@ints );
+ my @expected = split / \s+ /x, $expected_str;
+
+ is_deeply $decompressed, \@expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|1 3 2 4|3 4 4
+Example 2|1 1 2 2|1 2 2
+Example 3|3 1 3 2|1 1 1 2 2 2
diff --git a/challenge-326/athanasius/raku/ch-1.raku b/challenge-326/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..d7790f7a15
--- /dev/null
+++ b/challenge-326/athanasius/raku/ch-1.raku
@@ -0,0 +1,159 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 326
+=========================
+
+TASK #1
+-------
+*Day of the Year*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a date in the format YYYY-MM-DD.
+
+Write a script to find day number of the year that the given date represent.
+
+Example 1
+
+ Input: $date = '2025-02-02'
+ Output: 33
+
+ The 2nd Feb, 2025 is the 33rd day of the year.
+
+Example 2
+
+ Input: $date = '2025-04-10'
+ Output: 100
+
+Example 3
+
+ Input: $date = '2025-09-07'
+ Output: 250
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A valid date in the format "YYYY-MM-DD" is entered on the command-line.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 326, Task #1: Day of the Year (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A valid date in the format "YYYY-MM-DD"
+
+ Str $date where / ^ \d**4 \- \d\d \- \d\d $ /
+)
+#===============================================================================
+{
+ my Date $date-obj = Date.new: $date;
+
+ "Input: \$date = '$date'".put;
+
+ my UInt $day-of-year = find-day-of-year( $date-obj );
+
+ "Output: $day-of-year".put;
+
+ CATCH
+ {
+ default { error( .message ); }
+ }
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-day-of-year( Date:D $date --> UInt:D )
+#-------------------------------------------------------------------------------
+{
+ my Date $start = $date.truncated-to( 'year' );
+
+ return $date.daycount - $start.daycount + 1;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $date, $expected) = $line.split: / \| /;
+
+ for $test-name, $date, $expected
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my UInt $day-of-year = find-day-of-year( Date.new( $date ) );
+
+ is $day-of-year, $expected.Int, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error( Str:D $message )
+#-------------------------------------------------------------------------------
+{
+ "ERROR: $message".put;
+
+ USAGE();
+
+ exit 0;
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/;
+
+ $usage.put;
+}
+
+#-------------------------------------------------------------------------------
+sub test-data( --> Str:D )
+#-------------------------------------------------------------------------------
+{
+ return q:to/END/;
+ Example 1|2025-02-02| 33
+ Example 2|2025-04-10|100
+ Example 3|2025-09-07|250
+ END
+}
+
+################################################################################
diff --git a/challenge-326/athanasius/raku/ch-2.raku b/challenge-326/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..effc8858b1
--- /dev/null
+++ b/challenge-326/athanasius/raku/ch-2.raku
@@ -0,0 +1,167 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 326
+=========================
+
+TASK #2
+-------
+*Decompressed List*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers having even elements.
+
+Write a script to return the decompress[ed] list. To decompress, pick adjacent
+pair (i, j) and replace it with j, i times.
+
+Example 1
+
+ Input: @ints = (1, 3, 2, 4)
+ Output: (3, 4, 4)
+
+ Pair 1: (1, 3) => 3 one time => (3)
+ Pair 2: (2, 4) => 4 two times => (4, 4)
+
+Example 2
+
+ Input: @ints = (1, 1, 2, 2)
+ Output: (1, 2, 2)
+
+ Pair 1: (1, 1) => 1 one time => (1)
+ Pair 2: (2, 2) => 2 two times => (2, 2)
+
+Example 3
+
+ Input: @ints = (3, 1, 3, 2)
+ Output: (1, 1, 1, 2, 2, 2)
+
+ Pair 1: (3, 1) => 1 three times => (1, 1, 1)
+ Pair 2: (3, 2) => 2 three times => (2, 2, 2)
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Assumption
+----------
+"Positive" integers are greater than zero.
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A non-empty, even-sized list of positive integers is entered on the command-
+ line.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+subset Pos of Int where * > 0;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 326, Task #2: Decompressed List (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty, even-sized list of positive integers
+
+ *@ints where { .elems > 0 && .elems %% 2 && .all ~~ Pos:D }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my Pos @decompressed = decompress( @ints );
+
+ "Output: (%s)\n".printf: @decompressed.join: ', ';
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub decompress
+(
+ List:D[Pos:D] $ints where { $ints.elems %% 2 }
+--> List:D[Pos:D]
+)
+#-------------------------------------------------------------------------------
+{
+ my Pos @decompressed;
+
+ for @$ints -> Pos $count, Pos $elem
+ {
+ @decompressed.push: |( $elem xx $count );
+ }
+
+ return @decompressed;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $ints-str, $expd-str) = $line.split: / \| /;
+
+ for $test-name, $ints-str, $expd-str
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Pos @ints = $ints-str.split( / \s+ /, :skip-empty ).map: { .Int };
+ my Pos @decomp = decompress( @ints );
+ my Pos @expctd = $expd-str.split( / \s+ /, :skip-empty ).map: { .Int };
+
+ is-deeply @decomp, @expctd, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/;
+
+ $usage.put;
+}
+
+#-------------------------------------------------------------------------------
+sub test-data( --> Str:D )
+#-------------------------------------------------------------------------------
+{
+ return q:to/END/;
+ Example 1|1 3 2 4|3 4 4
+ Example 2|1 1 2 2|1 2 2
+ Example 3|3 1 3 2|1 1 1 2 2 2
+ END
+}
+
+################################################################################