aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobbie-hatley <Robbie.Hatley@gmail.com>2025-11-19 20:47:20 -0800
committerrobbie-hatley <Robbie.Hatley@gmail.com>2025-11-19 20:47:20 -0800
commitf201fcd5417aafad70e9390f5f8b80fac6aeff83 (patch)
tree012085c59c71da442fa4ef475c6b41a776138b70
parentaa283ea4bec57f330a917dba4a1c8b13102c6008 (diff)
downloadperlweeklychallenge-club-f201fcd5417aafad70e9390f5f8b80fac6aeff83.tar.gz
perlweeklychallenge-club-f201fcd5417aafad70e9390f5f8b80fac6aeff83.tar.bz2
perlweeklychallenge-club-f201fcd5417aafad70e9390f5f8b80fac6aeff83.zip
Robbie Hatley's solutions, in Perl, for The Weekly Challenge #348.
-rw-r--r--challenge-348/robbie-hatley/blog.txt1
-rwxr-xr-xchallenge-348/robbie-hatley/perl/ch-1.pl111
-rwxr-xr-xchallenge-348/robbie-hatley/perl/ch-2.pl116
3 files changed, 228 insertions, 0 deletions
diff --git a/challenge-348/robbie-hatley/blog.txt b/challenge-348/robbie-hatley/blog.txt
new file mode 100644
index 0000000000..7fe90d24f7
--- /dev/null
+++ b/challenge-348/robbie-hatley/blog.txt
@@ -0,0 +1 @@
+https://hatley-software.blogspot.com/2025/11/robbie-hatleys-solutions-in-perl-for_19.html
diff --git a/challenge-348/robbie-hatley/perl/ch-1.pl b/challenge-348/robbie-hatley/perl/ch-1.pl
new file mode 100755
index 0000000000..f58facc1ec
--- /dev/null
+++ b/challenge-348/robbie-hatley/perl/ch-1.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/env perl
+
+=pod
+
+--------------------------------------------------------------------------------------------------------------
+TITLE AND ATTRIBUTION:
+Solution in Perl for The Weekly Challenge 348-1,
+written by Robbie Hatley on Mon Nov 17, 2025.
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM DESCRIPTION:
+Task 348-1: String Alike
+Submitted by: Mohammad Sajid Anwar
+Write a script to find out whether a given string can be split
+into two halves of equal lengths, each with the same non-zero
+number of vowels.
+
+Example #1:
+Input: "textbook"
+Output: false
+1st half: "text" (1 vowel)
+2nd half: "book" (2 vowels)
+
+Example #2:
+Input: "book"
+Output: true
+1st half: "bo" (1 vowel)
+2nd half: "ok" (1 vowel)
+
+Example #3:
+Input: "AbCdEfGh"
+Output: true
+1st half: "AbCd" (1 vowel)
+2nd half: "EfGh" (1 vowel)
+
+Example #4:
+Input: "rhythmmyth"
+Output: false
+1st half: "rhyth" (0 vowel)
+2nd half: "mmyth" (0 vowel)
+
+Example #5:
+Input: "UmpireeAudio"
+Output: false
+1st half: "Umpire" (3 vowels)
+2nd half: "eAudio" (5 vowels)
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM NOTES:
+Firstly, if the string has odd length, return 'false'. Otherwise, just split the string in-half and count
+vowels in the halves, then use this logic:
+if ( $v1<1 || $v2<1 || $v1 != $v2 ) { return 'false' }
+else { return 'true' }
+That's assuming that "vowel" means "one of [aeiouAEIOU]". In order to ensure that accented Latin vowels are
+also counted as being "vowels", I use "NFD" from "Unicode::Normalize" to detach all combining marks from all
+letters, then lowercase, then delete all codepoints matching [^aeiou], then count remaining characters; if the
+two halves now have the same non-zero number of vowels, we can split, else we can't.
+
+--------------------------------------------------------------------------------------------------------------
+IO NOTES:
+Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a
+single-quoted array of double-quoted strings, in proper Perl syntax, like so:
+
+./ch-1.pl '("cucumber", "potato", "RÜTÀBÉGÀ", "onion")'
+
+Output is to STDOUT and will be each input followed by the corresponding output.
+
+=cut
+
+# ------------------------------------------------------------------------------------------------------------
+# PRAGMAS, MODULES, AND SUBS:
+
+ use v5.36;
+ use utf8::all;
+ use Unicode::Normalize 'NFD';
+
+ # Can we split a given string into two equal-length
+ # halves with equal non-zero numbers of vowels?
+ sub can_split ( $s ) {
+ my $l = length($s);
+ if ( 0 != $l % 2 ) { return 'false' }
+ my $s1 = substr $s, 0 , $l/2;
+ my $s2 = substr $s, $l/2, $l/2;
+ my $v1 = length(lc(NFD($s1)) =~ s/[^aeiou]//gr);
+ my $v2 = length(lc(NFD($s2)) =~ s/[^aeiou]//gr);
+ return 'false' if $v1<1 || $v2<1 || $v1 != $v2;
+ return 'true'}
+
+# ------------------------------------------------------------------------------------------------------------
+# INPUTS:
+my @strings = @ARGV ? eval($ARGV[0]) :
+(
+ "textbook", # false
+ "book", # true
+ "AbCdEfGh", # true
+ "rhythmmyth", # false
+ "UmpireeAudio", # false
+);
+
+# ------------------------------------------------------------------------------------------------------------
+# MAIN BODY OF PROGRAM:
+$"=', ';
+say '';
+print "Note: for each input string, we ask whether we can split it into\n"
+ . "two equal-length halves with equal, non-zero numbers of vowels.\n";
+for my $s (@strings) {
+ say '';
+ say "String = \"$s\"";
+ my $cs = can_split($s);
+ say "Can split? $cs"
+}
diff --git a/challenge-348/robbie-hatley/perl/ch-2.pl b/challenge-348/robbie-hatley/perl/ch-2.pl
new file mode 100755
index 0000000000..813d7d358b
--- /dev/null
+++ b/challenge-348/robbie-hatley/perl/ch-2.pl
@@ -0,0 +1,116 @@
+#!/usr/bin/env perl
+
+=pod
+
+--------------------------------------------------------------------------------------------------------------
+TITLE AND ATTRIBUTION:
+Solution in Perl for The Weekly Challenge 348-2,
+written by Robbie Hatley on Mon Nov 17, 2025.
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM DESCRIPTION:
+Task 348-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
+One operation: "Add 15 minutes".
+
+Example 2
+Input: $source = "11:55"
+ $target = "12:15"
+Output: 2
+Two operations: "Add 15 minutes", "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: "Add 60 minutes", "Add 5 minutes".
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM NOTES:
+To solve this problem, I'll use this procedure:
+1. Convert both times to minutes ($source -> $s, $target -> $t).
+2. while ( $t < $s ) {$t += 1440}
+3. my $ops = 0;
+4. while ( $t - $s >= 60 ) {$s += 60; ++$ops}
+5. while ( $t - $s >= 15 ) {$s += 15; ++$ops}
+6. while ( $t - $s >= 5 ) {$s += 5; ++$ops}
+7. while ( $t - $s >= 1 ) {$s += 1; ++$ops}
+8. return $ops
+
+--------------------------------------------------------------------------------------------------------------
+IO NOTES:
+Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a
+single-quoted array of arrays of two double-quoted 24H times, in proper Perl syntax, like so:
+
+./ch-2.pl '(["03:28", "23:19"],["21:44", "20:44"])'
+
+Output is to STDOUT and will be each input followed by the corresponding output.
+
+=cut
+
+# ------------------------------------------------------------------------------------------------------------
+# PRAGMAS, MODULES, AND SUBS:
+
+ use v5.36;
+ use utf8::all;
+
+ # Return number of operations to convert source to target:
+ sub num_ops ( $src, $trg ) {
+ my $s = 60 * (0 + substr $src, 0, 2) + 1 * (0 + substr $src, 3, 2);
+ my $t = 60 * (0 + substr $trg, 0, 2) + 1 * (0 + substr $trg, 3, 2);
+ my $ops = 0;
+ while ( $t < $s ) {$t += 1440}
+ while ( $t - $s >= 60 ) {$s += 60; ++$ops}
+ while ( $t - $s >= 15 ) {$s += 15; ++$ops}
+ while ( $t - $s >= 5 ) {$s += 5; ++$ops}
+ while ( $t - $s >= 1 ) {$s += 1; ++$ops}
+ $ops}
+
+# ------------------------------------------------------------------------------------------------------------
+# INPUTS:
+my @arrays = @ARGV ? eval($ARGV[0]) :
+(
+ ["02:30", "02:45"], # 1
+ ["11:55", "12:15"], # 2
+ ["09:00", "13:00"], # 4
+ ["23:45", "00:30"], # 3
+ ["14:20", "15:25"], # 2
+);
+
+# ------------------------------------------------------------------------------------------------------------
+# MAIN BODY OF PROGRAM:
+$"=', ';
+for my $aref (@arrays) {
+ say '';
+ my $src = $aref->[0];
+ my $trg = $aref->[1];
+ say "Source time = $src";
+ say "Target time = $trg";
+ my $ops = num_ops($src, $trg);
+ say "Number of operations = $ops";
+}