aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-08-25 21:07:06 +0100
committerGitHub <noreply@github.com>2025-08-25 21:07:06 +0100
commit9449d88b9372cb9e1e6ea4d3efb81d6871f4517d (patch)
tree08383c6c5ed22ea02a0540c277bb66bbf15e4f7f
parent7db566e480887880f155dd8c66b08a550a834911 (diff)
parent40540cf5af0a7d3d1dabf8aca64401a3185ad03c (diff)
downloadperlweeklychallenge-club-9449d88b9372cb9e1e6ea4d3efb81d6871f4517d.tar.gz
perlweeklychallenge-club-9449d88b9372cb9e1e6ea4d3efb81d6871f4517d.tar.bz2
perlweeklychallenge-club-9449d88b9372cb9e1e6ea4d3efb81d6871f4517d.zip
Merge pull request #12574 from robbie-hatley/rh336
Robbie Hatley's solutions, in Perl, for The Weekly Challenge #336.
-rw-r--r--challenge-336/robbie-hatley/blog.txt1
-rwxr-xr-xchallenge-336/robbie-hatley/perl/ch-1.pl122
-rwxr-xr-xchallenge-336/robbie-hatley/perl/ch-2.pl156
3 files changed, 279 insertions, 0 deletions
diff --git a/challenge-336/robbie-hatley/blog.txt b/challenge-336/robbie-hatley/blog.txt
new file mode 100644
index 0000000000..6d9501756e
--- /dev/null
+++ b/challenge-336/robbie-hatley/blog.txt
@@ -0,0 +1 @@
+https://hatley-software.blogspot.com/2025/08/robbie-hatleys-solutions-in-perl-for_25.html
diff --git a/challenge-336/robbie-hatley/perl/ch-1.pl b/challenge-336/robbie-hatley/perl/ch-1.pl
new file mode 100755
index 0000000000..084a5cfd7c
--- /dev/null
+++ b/challenge-336/robbie-hatley/perl/ch-1.pl
@@ -0,0 +1,122 @@
+#!/usr/bin/env perl
+
+=pod
+
+--------------------------------------------------------------------------------------------------------------
+TITLE AND ATTRIBUTION:
+Solutions in Perl for The Weekly Challenge 336-1,
+written by Robbie Hatley on Mon Aug 25, 2025.
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM DESCRIPTION:
+Task 336-1: Equal Group
+Submitted by: Mohammad Sajid Anwar
+You are given an array of integers. Write a script to return
+true if the given array can be divided into one or more groups:
+each group must be of the same size as the others, with at least
+two members, and with all members having the same value.
+
+Example #1:
+Input: @ints = (1,1,2,2,2,2)
+Output: true
+Groups: (1,1), (2,2), (2,2)
+
+Example #2:
+Input: @ints = (1,1,1,2,2,2,3,3)
+Output: false
+Groups: (1,1,1), (2,2,2), (3,3)
+
+Example #3:
+Input: @ints = (5,5,5,5,5,5,7,7,7,7,7,7)
+Output: true
+Groups: (5,5,5,5,5,5), (7,7,7,7,7,7)
+
+Example #4:
+Input: @ints = (1,2,3,4)
+Output: false
+
+Example #5:
+Input: @ints = (8,8,9,9,10,10,11,11)
+Output: true
+Groups: (8,8), (9,9), (10,10), (11,11)
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM NOTES:
+Mathematically, this problem is equivalent to splitting the input array into equivalence groups based on
+integer equality. That can easily be done by using a hash %hash with key=integer and value=multiplicity.
+Then store keys sorted by increasing abundance in an array @sk. If any $hash{$sk[$idx]} is less than 2,
+or if any $hash{$sk[$idx]} is not divisible by $hash{$sk[0]}, return "false"; otherwise return "true".
+
+--------------------------------------------------------------------------------------------------------------
+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 integers, in proper Perl syntax, like so:
+
+./ch-1.pl '(["bat","cat","hat"],[37,-2,37,-3,37,-3,37,-2],[5,3,9,5,3,9,5])'
+
+Output is to STDOUT and will be each input followed by the corresponding output.
+
+=cut
+
+# ------------------------------------------------------------------------------------------------------------
+# PRAGMAS, MODULES, AND SUBS:
+
+ use v5.36;
+ # Is a referred-to array an array of integers?
+ sub are_ints ($aref) {
+ for (@$aref){
+ if ($_!~m/^-[1-9]\d*$|^0$|^[1-9]\d*$/){
+ return 0}}
+ return 1}
+ # Can an array of integers be grouped as one-or-more groups
+ # of equal integers, two-or-more in size, with the sizes of
+ # all such groups being equal?
+ sub equal_group ($aref) {
+ # Make and load a hash of integer abundances:
+ my %hash;++$hash{$_} for @$aref;
+ # Get a copy of the keys, sorted by increasing abundance:
+ my @sk = sort {$hash{$a}<=>$hash{$b}} keys %hash;
+ for (0..$#sk) {
+ # Return 'false' if smallest group has fewer
+ # than 2 elements:
+ return 'false' if $hash{$sk[$_]}<2;
+ # Return 'false' if current-group size is not
+ # divisible by group-0 size:
+ return 'false' if 0!=$hash{$sk[$_]}%$hash{$sk[0]}}
+ # If we get to here, this array is equal-group-able:
+ return 'true'}
+
+# ------------------------------------------------------------------------------------------------------------
+# INPUTS:
+my @arrays = @ARGV ? eval($ARGV[0]) :
+(
+ # Example 1 input:
+ [1,1,2,2,2,2],
+ # Expected output: true
+
+ # Example 2 input:
+ [1,1,1,2,2,2,3,3],
+ # Expected output: false
+
+ # Example 3 input:
+ [5,5,5,5,5,5,7,7,7,7,7,7],
+ # Expected output: true
+
+ # Example 4 input:
+ [1,2,3,4],
+ # Expected output: false
+
+ # Example 5 input:
+ [8,8,9,9,10,10,11,11],
+ # Expected output: true
+);
+
+# ------------------------------------------------------------------------------------------------------------
+# MAIN BODY OF PROGRAM:
+$"=', ';
+for my $aref (@arrays) {
+ say '';
+ say "Array = (@$aref)";
+ if (!are_ints($aref)){say "Not an array of ints.";next}
+ my $eg = equal_group($aref);
+ say "Equal group? $eg"}
diff --git a/challenge-336/robbie-hatley/perl/ch-2.pl b/challenge-336/robbie-hatley/perl/ch-2.pl
new file mode 100755
index 0000000000..e13e32a51f
--- /dev/null
+++ b/challenge-336/robbie-hatley/perl/ch-2.pl
@@ -0,0 +1,156 @@
+#!/usr/bin/env perl
+
+=pod
+
+--------------------------------------------------------------------------------------------------------------
+TITLE AND ATTRIBUTION:
+Solutions in Perl for The Weekly Challenge 336-2,
+written by Robbie Hatley on Mon Aug 25, 2025.
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM DESCRIPTION:
+Task 336-2: Final Score
+Submitted by: Mohammad Sajid Anwar
+You are given an array of scores by a team. Write a script to
+find the total score of the given team. The score can be any
+integer, +, C or D. The + adds the sum of previous two scores.
+The score C invalidates the previous score. The score D will
+double the previous score.
+
+Example #1:
+Input: @scores = ("5","2","C","D","+")
+Output: 30
+Round 1: 5
+Round 2: 5 + 2
+Round 3: 5 (invalidate the previous score 2)
+Round 4: 5 + 10 (double the previous score 5)
+Round 5: 5 + 10 + 15 (sum of previous two scores)
+Total Scores: 30
+
+Example #2:
+Input: @scores = ("5","-2","4","C","D","9","+","+")
+Output: 27
+Round 1: 5
+Round 2: 5 + (-2)
+Round 3: 5 + (-2) + 4
+Round 4: 5 + (-2) (invalidate the previous score 4)
+Round 5: 5 + (-2) + (-4) (double the previous score -2)
+Round 6: 5 + (-2) + (-4) + 9
+Round 7: 5 + (-2) + (-4) + 9 + 5 (sum of previous two scores)
+Round 8: 5 + (-2) + (-4) + 9 + 5 + 14 (sum of previous two scores)
+Total Scores: 27
+
+Example #3:
+Input: @scores = ("7","D","D","C","+","3")
+Output: 45
+Round 1: 7
+Round 2: 7 + 14 (double the previous score 7)
+Round 3: 7 + 14 + 28 (double the previous score 14)
+Round 4: 7 + 14 (invalidate the previous score 28)
+Round 5: 7 + 14 + 21 (sum of previous two scores)
+Round 6: 7 + 14 + 21 + 3
+Total Scores: 45
+
+Example #4:
+Input: @scores = ("-5","-10","+","D","C","+")
+Output: -55
+Round 1: (-5)
+Round 2: (-5) + (-10)
+Round 3: (-5) + (-10) + (-15) (sum of previous two scores)
+Round 4: (-5) + (-10) + (-15) + (-30) (double the previous score -15)
+Round 5: (-5) + (-10) + (-15) (invalidate the previous score -30)
+Round 6: (-5) + (-10) + (-15) + (-25) (sum of previous two scores)
+Total Scores: -55
+
+Example #5:
+Input: @scores = ("3","6","+","D","C","8","+","D","-2","C","+")
+Output: 128
+Round 1: 3
+Round 2: 3 + 6
+Round 3: 3 + 6 + 9 (sum of previous two scores)
+Round 4: 3 + 6 + 9 + 18 (double the previous score 9)
+Round 5: 3 + 6 + 9 (invalidate the previous score 18)
+Round 6: 3 + 6 + 9 + 8
+Round 7: 3 + 6 + 9 + 8 + 17 (sum of previous two scores)
+Round 8: 3 + 6 + 9 + 8 + 17 + 34 (double the previous score 17)
+Round 9: 3 + 6 + 9 + 8 + 17 + 34 + (-2)
+Round 10: 3 + 6 + 9 + 8 + 17 + 34 (invalidate the previous score -2)
+Round 11: 3 + 6 + 9 + 8 + 17 + 34 + 51 (sum of previous two scores)
+Total Scores: 128
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM NOTES:
+I'll iterate through the partial scores from left to right, replacing each with an integer, depending on what
+each partial score is saying to do. I'll use "switch" and "case" from CPAN module "Switch" to select actions
+based on each partial score. Then when all partial scores have been converted to integers, I'll use "sum0"
+from CPAN module "List::Util" to sum the integers, giving the final score.
+
+--------------------------------------------------------------------------------------------------------------
+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 double-quoted strings, in proper Perl syntax, like so:
+
+./ch-2.pl '(["3","-5","D","bat","C","73"],["3","92","-47","D","D","D","1117846","C"])'
+
+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 Switch;
+ use List::Util 'sum0';
+ # Calculate the final score:
+ sub final_score ($aref) {
+ # Make a working copy of our partial scores:
+ my @ps = @$aref;
+ # For each partial score, replace it with an integer:
+ for ( my $idx = 0 ; $idx <= $#ps ; ++$idx ) {
+ switch ($ps[$idx]) {
+ # If item is quoted integer, just add 0:
+ case /^-[1-9]\d*$|^0$|^[1-9]\d*$/ {
+ $ps[$idx]=0+$ps[$idx]}
+ # Add previous two:
+ case "+" {
+ switch ($idx) {
+ case 0 {$ps[$idx]=0}
+ case 1 {$ps[$idx]=$ps[0]}
+ else {$ps[$idx]=$ps[$idx-2]+$ps[$idx-1]}}}
+ # Cancel previous:
+ case "C" {
+ switch ($idx) {
+ case 0 {splice @ps,0,1;--$idx}
+ else {splice @ps,$idx-1,2;$idx-=2}}}
+ # Double previous:
+ case "D" {
+ switch ($idx) {
+ case 0 {$ps[$idx]=0}
+ else {$ps[$idx]=2*$ps[$idx-1]}}}
+ # Elide invalid partial scores:
+ else {splice @ps,$idx,1;--$idx}}}
+ # Tally and return the final score:
+ sum0 @ps}
+
+# ------------------------------------------------------------------------------------------------------------
+# INPUTS:
+my @arrays = @ARGV ? eval($ARGV[0]) :
+(
+ ["5","2","C","D","+"], # Expected final score: 30
+ ["5","-2","4","C","D","9","+","+"], # Expected final score: 27
+ ["7","D","D","C","+","3"], # Expected final score: 45
+ ["-5","-10","+","D","C","+"], # Expected final score: -55
+ ["3","6","+","D","C","8","+","D","-2","C","+"], # Expected final score: 128
+);
+
+# ------------------------------------------------------------------------------------------------------------
+# MAIN BODY OF PROGRAM:
+$"=', ';
+for my $aref (@arrays) {
+ say '';
+ say "Partial scores = (@$aref)";
+ my $fs = final_score($aref);
+ say "Final score = $fs";
+}