diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-11-18 10:15:55 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-18 10:15:55 +0000 |
| commit | 544648414e896c492fe390f115a5f0a5bba61bc0 (patch) | |
| tree | c53e008ce142d619671efe07c5a78ee19629aec0 | |
| parent | cd0292336ec7a0dee0b836d703b360dc242e6782 (diff) | |
| parent | 1d082deee4a1cf7b2e0a9ddbf946ab38cd1f888d (diff) | |
| download | perlweeklychallenge-club-544648414e896c492fe390f115a5f0a5bba61bc0.tar.gz perlweeklychallenge-club-544648414e896c492fe390f115a5f0a5bba61bc0.tar.bz2 perlweeklychallenge-club-544648414e896c492fe390f115a5f0a5bba61bc0.zip | |
Merge pull request #13053 from PerlMonk-Athanasius/branch-for-challenge-348
Perl & Raku solutions to Tasks 1 & 2 for Week 348
| -rw-r--r-- | challenge-348/athanasius/perl/ch-1.pl | 185 | ||||
| -rw-r--r-- | challenge-348/athanasius/perl/ch-2.pl | 220 | ||||
| -rw-r--r-- | challenge-348/athanasius/raku/ch-1.raku | 171 | ||||
| -rw-r--r-- | challenge-348/athanasius/raku/ch-2.raku | 199 |
4 files changed, 775 insertions, 0 deletions
diff --git a/challenge-348/athanasius/perl/ch-1.pl b/challenge-348/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..766f2932da --- /dev/null +++ b/challenge-348/athanasius/perl/ch-1.pl @@ -0,0 +1,185 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 348 +========================= + +TASK #1 +------- +*String Alike* + +Submitted by: Mohammad Sajid Anwar + +You are given a string of even length. + +Write a script to find out whether the given string can be split into two halves +of equal lengths, each with the same non-zero number of vowels. + +Example 1 + + Input: $str = "textbook" + Output: false + + 1st half: "text" (1 vowel) + 2nd half: "book" (2 vowels) + +Example 2 + + Input: $str = "book" + Output: true + + 1st half: "bo" (1 vowel) + 2nd half: "ok" (1 vowel) + +Example 3 + + Input: $str = "AbCdEfGh" + Output: true + + 1st half: "AbCd" (1 vowel) + 2nd half: "EfGh" (1 vowel) + +Example 4 + + Input: $str = "rhythmmyth" + Output: false + + 1st half: "rhyth" (0 vowel) + 2nd half: "mmyth" (0 vowel) + +Example 5 + + Input: $str = "UmpireeAudio" + Output: false + + 1st half: "Umpire" (3 vowels) + 2nd half: "eAudio" (5 vowels) + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A string of even length is entered on the command-line. + +=cut +#=============================================================================== + +use v5.38.2; # Enables strictures +use warnings; +use Const::Fast; +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 <str> + perl $0 + + <str> A string of even length +END +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 348, Task #1: String Alike (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + + if ($argc == 0) + { + run_tests(); + } + elsif ($argc == 1) + { + my $str = $ARGV[0]; + + length( $str ) % 2 == 0 or error( qq[String "$str" is of odd length] ); + + print qq[Input: \$str = "$str"\n]; + + my $alike = string_alike( $str ); + + printf "Output: %s\n", $alike ? 'true' : 'false'; + } + else + { + error( "Expected 1 or 0 command-line arguments, found $argc" ); + } +} + +#------------------------------------------------------------------------------- +sub string_alike +#------------------------------------------------------------------------------- +{ + my ($str) = @_; + my $str_len = length $str; + $str_len % 2 == 0 or die qq[String "$str" is of odd length]; + my $half_len = $str_len / 2; + my $lhs = substr $str, 0, $half_len; + my $lhs_count = ($lhs =~ tr/AEIOUaeiou//); + my $rhs = substr $str, $half_len; + my $rhs_count = ($rhs =~ tr/AEIOUaeiou//); + + return $lhs_count > 0 && $lhs_count == $rhs_count; +} + +#------------------------------------------------------------------------------- +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 $alike = string_alike( $str ); + my $alike_str = $alike ? 'true' : 'false'; + + is $alike_str, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "\nERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|textbook |false +Example 2|book |true +Example 3|AbCdEfGh |true +Example 4|rhythmmyth |false +Example 5|UmpireeAudio|false diff --git a/challenge-348/athanasius/perl/ch-2.pl b/challenge-348/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..86b8c2420b --- /dev/null +++ b/challenge-348/athanasius/perl/ch-2.pl @@ -0,0 +1,220 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 348 +========================= + +TASK #2 +------- +*Convert Time* + +Submitted by: Mohammad Sajid Anwar + +You are given two strings, $source and $target, containing time in 24-hour time +form. + +Write a script to convert the source into target by performing one of the +following operations: + + 1. Add 1 minute + 2. Add 5 minutes + 3. Add 15 minutes + 4. Add 60 minutes + +Find the total operations needed to get to the target. + +Example 1 + + Input: $source = "02:30" + $target = "02:45" + Output: 1 + + Just one operation i.e. "Add 15 minutes". + +Example 2 + + Input: $source = "11:55" + $target = "12:15" + Output: 2 + + Two operations i.e. "Add 15 minutes" followed by "Add 5 minutes". + +Example 3 + + Input: $source = "09:00" + $target = "13:00" + Output: 4 + + Four operations of "Add 60 minutes". + +Example 4 + + Input: $source = "23:45" + $target = "00:30" + Output: 3 + + Three operations of "Add 15 minutes". + +Example 5 + + Input: $source = "14:20" + $target = "15:25" + Output: 2 + + Two operations, one "Add 60 minutes" and one "Add 5 minutes" + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2025 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A source time and a target time, both in 24-hour format, are entered on the + command-line. + +=cut +#=============================================================================== + +use v5.38.2; # Enables strictures +use warnings; +use Const::Fast; +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 <source> <target> + perl $0 + + <source> Source time in 24-hour format + <target> Target time in 24-hour format +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 348, Task #2: Convert Time (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + + if ($argc == 0) + { + run_tests(); + } + elsif ($argc == 2) + { + my ($source, $target) = @ARGV; + + for ($source, $target) + { + / ^ (\d\d) \: (\d\d) $ /x or error( qq[Invalid time "$_"] ); + 0 <= $1 < 24 or error( qq[Invalid hours "$1"] ); + 0 <= $2 < 60 or error( qq[Invalid minutes "$2"] ); + } + + print qq[Input: \$source = "$source"\n]; + print qq[ \$target = "$target"\n]; + + my $operations = convert_time( $source, $target ); + + print "Output: $operations\n"; + } + else + { + error( "Expected 0 or 2 command-line arguments, found $argc" ); + } +} + +#------------------------------------------------------------------------------- +sub convert_time +#------------------------------------------------------------------------------- +{ + my ($source, $target) = @_; + + $source =~ / ^ (\d\d) \: (\d\d) $ /x or die qq[Invalid time "$source"]; + 0 <= $1 < 24 or die qq[Invalid hours "$1"]; + 0 <= $2 < 60 or die qq[Invalid minutes "$2"]; + + my $start = ($1 * 60) + $2; + + $target =~ / ^ (\d\d) \: (\d\d) $ /x or die qq[Invalid time "$target"]; + 0 <= $1 < 24 or die qq[Invalid hours "$1"]; + 0 <= $2 < 60 or die qq[Invalid minutes "$2"]; + + my $end = ($1 * 60) + $2; + my $diff = $end - $start; + $diff += (60 * 24) if $diff < 0; + my $ops = 0; + + for my $n (60, 15, 5, 1) + { + $ops += int( $diff / $n ); + $diff %= $n; + } + + $diff == 0 or die 'Logic error'; + + return $ops; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $source, $target, $expected) = split / \| /x, $line; + + for ($test_name, $source, $target, $expected) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my $operations = convert_time( $source, $target ); + + is $operations, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1 |02:30|02:45| 1 +Example 2 |11:55|12:15| 2 +Example 3 |09:00|13:00| 4 +Example 4 |23:45|00:30| 3 +Example 5 |14:20|15:25| 2 +Same time |09:17|09:17| 0 +One minute |17:36|17:37| 1 +Almost 1 day|17:36|17:35|32 diff --git a/challenge-348/athanasius/raku/ch-1.raku b/challenge-348/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..ead92d8521 --- /dev/null +++ b/challenge-348/athanasius/raku/ch-1.raku @@ -0,0 +1,171 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 348 +========================= + +TASK #1 +------- +*String Alike* + +Submitted by: Mohammad Sajid Anwar + +You are given a string of even length. + +Write a script to find out whether the given string can be split into two halves +of equal lengths, each with the same non-zero number of vowels. + +Example 1 + + Input: $str = "textbook" + Output: false + + 1st half: "text" (1 vowel) + 2nd half: "book" (2 vowels) + +Example 2 + + Input: $str = "book" + Output: true + + 1st half: "bo" (1 vowel) + 2nd half: "ok" (1 vowel) + +Example 3 + + Input: $str = "AbCdEfGh" + Output: true + + 1st half: "AbCd" (1 vowel) + 2nd half: "EfGh" (1 vowel) + +Example 4 + + Input: $str = "rhythmmyth" + Output: false + + 1st half: "rhyth" (0 vowel) + 2nd half: "mmyth" (0 vowel) + +Example 5 + + Input: $str = "UmpireeAudio" + Output: false + + 1st half: "Umpire" (3 vowels) + 2nd half: "eAudio" (5 vowels) + +=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 of even length is entered on the command-line. + +=end comment +#=============================================================================== + +use Test; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 348, Task #1: String Alike (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + Str:D $str where { .chars %% 2 } #= A string of even length +) +#=============================================================================== +{ + qq[Input: \$str = "$str"].put; + + my Bool $alike = string-alike( $str ); + + "Output: %s\n".printf: $alike ?? 'true' !! 'false'; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub string-alike( Str:D $str where { .chars %% 2 } --> Bool:D ) +#------------------------------------------------------------------------------- +{ + my UInt $str-len = $str.chars; + my UInt $half-len = ($str-len / 2).Int; + my Str $lhs = $str.substr: 0, $half-len; + my UInt $lhs-count = $lhs.comb( / :i <[ AEIOU ]> / ).elems; + my Str $rhs = $str.substr: $half-len; + my UInt $rhs-count = $rhs.comb( / :i <[ AEIOU ]> / ).elems; + + return $lhs-count > 0 && $lhs-count == $rhs-count; +} + +#------------------------------------------------------------------------------- +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 Bool $alike = string-alike( $str ); + my Str $alike-str = $alike ?? 'true' !! 'false'; + + is $alike-str, $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|textbook |false + Example 2|book |true + Example 3|AbCdEfGh |true + Example 4|rhythmmyth |false + Example 5|UmpireeAudio|false + END +} + +################################################################################ diff --git a/challenge-348/athanasius/raku/ch-2.raku b/challenge-348/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..3f4ee0eedd --- /dev/null +++ b/challenge-348/athanasius/raku/ch-2.raku @@ -0,0 +1,199 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 348 +========================= + +TASK #2 +------- +*Convert Time* + +Submitted by: Mohammad Sajid Anwar + +You are given two strings, $source and $target, containing time in 24-hour time +form. + +Write a script to convert the source into target by performing one of the +following operations: + + 1. Add 1 minute + 2. Add 5 minutes + 3. Add 15 minutes + 4. Add 60 minutes + +Find the total operations needed to get to the target. + +Example 1 + + Input: $source = "02:30" + $target = "02:45" + Output: 1 + + Just one operation i.e. "Add 15 minutes". + +Example 2 + + Input: $source = "11:55" + $target = "12:15" + Output: 2 + + Two operations i.e. "Add 15 minutes" followed by "Add 5 minutes". + +Example 3 + + Input: $source = "09:00" + $target = "13:00" + Output: 4 + + Four operations of "Add 60 minutes". + +Example 4 + + Input: $source = "23:45" + $target = "00:30" + Output: 3 + + Three operations of "Add 15 minutes". + +Example 5 + + Input: $source = "14:20" + $target = "15:25" + Output: 2 + + Two operations, one "Add 60 minutes" and one "Add 5 minutes" + +=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 source time and a target time, both in 24-hour format, are entered on the + command-line. + +=end comment +#=============================================================================== + +use Test; + +subset Time of Str where { / ^ (\d\d) \: (\d\d) $ / && 0 <= $0 < 24 + && 0 <= $1 < 60 }; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 348, Task #2: Convert Time (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + Time:D $source, #= Source time in 24-hour format + Time:D $target #= Target time in 24-hour format +) +#=============================================================================== +{ + qq[Input: \$source = "$source"].put; + qq[ \$target = "$target"].put; + + my UInt $operations = convert-time( $source, $target ); + + "Output: $operations".put; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub convert-time( Time:D $source, Time:D $target --> UInt:D ) +#------------------------------------------------------------------------------- +{ + $source ~~ / ^ (\d\d) \: (\d\d) $ /; + + my UInt $start = ($0 * 60) + $1; + + $target ~~ / ^ (\d\d) \: (\d\d) $ /; + + my UInt $end = ($0 * 60) + $1; + my Int $diff = $end - $start; + $diff += (60 * 24) if $diff < 0; + my UInt $ops = 0; + + for 60, 15, 5, 1 -> UInt $n + { + $ops += $diff div $n; + $diff %= $n; + } + + $diff == 0 or die 'Logic error'; + + return $ops; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $source, $target, $expected) = $line.split: / \| /; + + for $test-name, $source, $target, $expected + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my UInt $operations = convert-time( $source, $target ); + + is $operations, $expected.Int, $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 |02:30|02:45| 1 + Example 2 |11:55|12:15| 2 + Example 3 |09:00|13:00| 4 + Example 4 |23:45|00:30| 3 + Example 5 |14:20|15:25| 2 + Same time |09:17|09:17| 0 + One minute |17:36|17:37| 1 + Almost 1 day|17:36|17:35|32 + END +} + +################################################################################ |
