aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-11-18 10:15:55 +0000
committerGitHub <noreply@github.com>2025-11-18 10:15:55 +0000
commit544648414e896c492fe390f115a5f0a5bba61bc0 (patch)
treec53e008ce142d619671efe07c5a78ee19629aec0
parentcd0292336ec7a0dee0b836d703b360dc242e6782 (diff)
parent1d082deee4a1cf7b2e0a9ddbf946ab38cd1f888d (diff)
downloadperlweeklychallenge-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.pl185
-rw-r--r--challenge-348/athanasius/perl/ch-2.pl220
-rw-r--r--challenge-348/athanasius/raku/ch-1.raku171
-rw-r--r--challenge-348/athanasius/raku/ch-2.raku199
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
+}
+
+################################################################################