diff options
| author | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2025-07-29 18:05:32 +1000 |
|---|---|---|
| committer | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2025-07-29 18:05:32 +1000 |
| commit | 1ac59ef78e959c4a87834a149b4a071de4a56cee (patch) | |
| tree | 73ab758ccf115129b4faf77a1b774c7586bc1e7a | |
| parent | 1ff2c9796a511d63231d3757acb27e4046a91fb2 (diff) | |
| download | perlweeklychallenge-club-1ac59ef78e959c4a87834a149b4a071de4a56cee.tar.gz perlweeklychallenge-club-1ac59ef78e959c4a87834a149b4a071de4a56cee.tar.bz2 perlweeklychallenge-club-1ac59ef78e959c4a87834a149b4a071de4a56cee.zip | |
Perl & Raku solutions to Tasks 1 & 2 for Week 332
| -rw-r--r-- | challenge-332/athanasius/perl/ch-1.pl | 189 | ||||
| -rw-r--r-- | challenge-332/athanasius/perl/ch-2.pl | 178 | ||||
| -rw-r--r-- | challenge-332/athanasius/raku/ch-1.raku | 189 | ||||
| -rw-r--r-- | challenge-332/athanasius/raku/ch-2.raku | 165 |
4 files changed, 721 insertions, 0 deletions
diff --git a/challenge-332/athanasius/perl/ch-1.pl b/challenge-332/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..8d9a85b77d --- /dev/null +++ b/challenge-332/athanasius/perl/ch-1.pl @@ -0,0 +1,189 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 332 +========================= + +TASK #1 +------- +*Binary Date* + +Submitted by: Mohammad Sajid Anwar + +You are given a date in the format YYYY-MM-DD. + +Write a script to convert it into binary date. + +Example 1 + + Input: $date = "2025-07-26" + Output: "11111101001-111-11010" + +Example 2 + + Input: $date = "2000-02-02" + Output: "11111010000-10-10" + +Example 3 + + Input: $date = "2024-12-31" + Output: "11111101000-1100-11111" + +=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. + +Assumption +---------- +Dates must be valid. + +=cut +#=============================================================================== + +use v5.32; # Enables strictures +use warnings; +use Const::Fast; +use DateTime; +use Devel::Assert qw( on ); +use Test::More; +use Try::Tiny; + +const my $DATE_RE => qr/ ^ (\d{4}) \- (\d\d) \- (\d\d) $ /x; +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 332, Task #1: Binary Date (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + + if ($argc == 0) + { + run_tests(); + } + elsif ($argc == 1) + { + my $date = $ARGV[ 0 ]; + + date_is_valid( $date ) or error( 'Invalid date' ); + + print qq[Input: \$date = "$date"\n]; + + my $bin_date = find_binary_date( $date ); + + print qq[Output: "$bin_date"\n]; + } + else + { + error( "Expected 1 or 0 command-line arguments, found $argc" ); + } +} + +#------------------------------------------------------------------------------- +sub find_binary_date +#------------------------------------------------------------------------------- +{ + my ($date) = @_; + + assert date_is_valid( $date ); + + $date =~ $DATE_RE; + + my $bin_year = sprintf '%b', $1; + my $bin_month = sprintf '%b', $2; + my $bin_day = sprintf '%b', $3; + + return "$bin_year-$bin_month-$bin_day"; +} + +#------------------------------------------------------------------------------- +sub date_is_valid # Returns a boolean value +#------------------------------------------------------------------------------- +{ + my ($date) = @_; + my $result = ''; + + if ($date =~ $DATE_RE) + { + $result = 1; + + try + { + DateTime->new( year => $1, month => $2, day => $3 ); + } + catch + { + $result = ''; + } + } + + return $result; +} + +#------------------------------------------------------------------------------- +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 $bin_date = find_binary_date( $date ); + + is $bin_date, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|2025-07-26|11111101001-111-11010 +Example 2|2000-02-02|11111010000-10-10 +Example 3|2024-12-31|11111101000-1100-11111 diff --git a/challenge-332/athanasius/perl/ch-2.pl b/challenge-332/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..02813904db --- /dev/null +++ b/challenge-332/athanasius/perl/ch-2.pl @@ -0,0 +1,178 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 332 +========================= + +TASK #2 +------- +*Odd Letters* + +Submitted by: Mohammad Sajid Anwar + +You are given a string. + +Write a script to find out if each letter in the given string appeared odd +number of times. + +Example 1 + + Input: $str = "weekly" + Output: false + + w: 1 time + e: 2 times + k: 1 time + l: 1 time + y: 1 time + + The letter 'e' appeared 2 times i.e. even. + +Example 2 + + Input: $str = "perl" + Output: true + +Example 3 + + Input: $source = "challenge" + Output: false + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A string is entered on the command-line. + +Assumptions +----------- +1. Non-letter characters in the string are ignored. +2. The identification of a letter is not case-sensitive; so, e.g., 'a' and 'A' + are considered the same letter. + +=cut +#=============================================================================== + +use v5.32; # Enables strictures +use warnings; +use Const::Fast; +use Devel::Assert qw( on ); +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 <str> + perl $0 + + <str> A string +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 332, Task #2: Odd Letters (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + + if ($argc == 0) + { + run_tests(); + } + elsif ($argc == 1) + { + my ($str) = @ARGV; + + print qq[Input: \$str = "$str"\n]; + + my $all_odd = all_letters_odd( $str ); + + printf "Output: %s\n", $all_odd ? 'true' : 'false'; + } + else + { + error( "Expected 1 or 0 command-line arguments, found $argc" ); + } +} + +#------------------------------------------------------------------------------- +sub all_letters_odd +#------------------------------------------------------------------------------- +{ + my ($str) = @_; + my @chars = split //, $str; + my %dict; + + for my $char (@chars) + { + ++$dict{ lc $char } if $char =~ / ^ [A-Za-z] $ /x; + } + + for my $val (values %dict) + { + return '' if $val % 2 == 0; + } + + return 1; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $str, $expected) = split / \| /x, $line; + + for ($test_name, $str, $expected) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my $all_odd = all_letters_odd( $str ) ? 'true' : 'false'; + + is $all_odd, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1 |weekly |false +Example 2 |perl |true +Example 3 |challenge|false +Mixed case 1|Test1 |false +Mixed case 2|**ee4E%% |true diff --git a/challenge-332/athanasius/raku/ch-1.raku b/challenge-332/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..3f5fd7448a --- /dev/null +++ b/challenge-332/athanasius/raku/ch-1.raku @@ -0,0 +1,189 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 332 +========================= + +TASK #1 +------- +*Binary Date* + +Submitted by: Mohammad Sajid Anwar + +You are given a date in the format YYYY-MM-DD. + +Write a script to convert it into binary date. + +Example 1 + + Input: $date = "2025-07-26" + Output: "11111101001-111-11010" + +Example 2 + + Input: $date = "2000-02-02" + Output: "11111010000-10-10" + +Example 3 + + Input: $date = "2024-12-31" + Output: "11111101000-1100-11111" + +=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. + +Assumption +---------- +Dates must be valid. + +=end comment +#=============================================================================== + +use Test; + +my regex Date { ^ (\d**4) \- (\d\d) \- (\d\d) $ }; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 332, Task #1: Binary Date (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + Str:D $date where m/ <Date> / #= A valid date in the format "YYYY-MM-DD" +) +#=============================================================================== +{ + my Str $msg = date-is-valid( $date ); + $msg and error( "Invalid date: $msg" ); + + qq[Input: \$date = "$date"].put; + + my Str $bin-date = find-binary-date( $date ); + + qq[Output: "$bin-date"].put; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub find-binary-date( Str:D $str where m/ <date=Date> / --> Str:D ) +#------------------------------------------------------------------------------- +{ + my Str $msg = date-is-valid( $str ); + $msg and die( "Invalid date: $msg" ); + + my Str $bin-year = $<date>[ 0 ].Int.base( 2 ); + my Str $bin-month = $<date>[ 1 ].Int.base( 2 ); + my Str $bin-day = $<date>[ 2 ].Int.base( 2 ); + + return $bin-year ~ '-' ~ $bin-month ~ '-' ~ $bin-day; +} + +#------------------------------------------------------------------------------- +sub date-is-valid +( + Str:D $date +--> Str:D #= Returns the empty string if the date is valid; + #= otherwise, returns an error message +) +#------------------------------------------------------------------------------- +{ + my Str $result = ''; + + try + { + CATCH + { + when X::Temporal + { + $result = .message; + } + } + + Date.new: $date; + } + + return $result; +} + +#------------------------------------------------------------------------------- +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 Str $bin-date = find-binary-date( $date ); + + is $bin-date, $expected, $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-07-26|11111101001-111-11010 + Example 2|2000-02-02|11111010000-10-10 + Example 3|2024-12-31|11111101000-1100-11111 + END +} + +################################################################################ diff --git a/challenge-332/athanasius/raku/ch-2.raku b/challenge-332/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..a35248cd92 --- /dev/null +++ b/challenge-332/athanasius/raku/ch-2.raku @@ -0,0 +1,165 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 332 +========================= + +TASK #2 +------- +*Odd Letters* + +Submitted by: Mohammad Sajid Anwar + +You are given a string. + +Write a script to find out if each letter in the given string appeared odd +number of times. + +Example 1 + + Input: $str = "weekly" + Output: false + + w: 1 time + e: 2 times + k: 1 time + l: 1 time + y: 1 time + + The letter 'e' appeared 2 times i.e. even. + +Example 2 + + Input: $str = "perl" + Output: true + +Example 3 + + Input: $source = "challenge" + Output: false + +=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 string is entered on the command-line. + +Assumptions +----------- +1. Non-letter characters in the string are ignored. +2. The identification of a letter is not case-sensitive; so, e.g., 'a' and 'A' + are considered the same letter. + +=end comment +#=============================================================================== + +use Test; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 332, Task #2: Odd Letters (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + Str:D $str #= A string +) +#=============================================================================== +{ + qq[Input: \$str = "$str"].put; + + my Bool $all-odd = all-letters-odd( $str ); + + "Output: %s\n".printf: $all-odd ?? 'true' !! 'false'; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub all-letters-odd( Str:D $str --> Bool:D ) +#------------------------------------------------------------------------------- +{ + my UInt %dict; + my Str @chars = $str.split: '', :skip-empty; + + for @chars -> Str $char + { + ++%dict{ $char.lc } if $char ~~ / ^ <[ A..Z a..z ]> $ /; + } + + for %dict.values -> UInt $val + { + return False if $val %% 2; + } + + return True; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $str, $expected) = $line.split: / \| /; + + for $test-name, $str, $expected + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Str $all-odd = all-letters-odd( $str ) ?? 'true' !! 'false'; + + is $all-odd, $expected, $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 |weekly |false + Example 2 |perl |true + Example 3 |challenge|false + Mixed case 1|Test1 |false + Mixed case 2|**ee4E%% |true + END +} + +################################################################################ |
