aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-11-29 15:31:51 +0000
committerGitHub <noreply@github.com>2023-11-29 15:31:51 +0000
commit89c1b586fb64ac8da56fa5fd43e1a8efcc576607 (patch)
tree32d099beaddc54116ac1a975afa16b9312ff8a98
parentd6ff45101a313dd84d56e359b2e4a413178ebfac (diff)
parent6f564f19317e2684026f39a3e800558757847631 (diff)
downloadperlweeklychallenge-club-89c1b586fb64ac8da56fa5fd43e1a8efcc576607.tar.gz
perlweeklychallenge-club-89c1b586fb64ac8da56fa5fd43e1a8efcc576607.tar.bz2
perlweeklychallenge-club-89c1b586fb64ac8da56fa5fd43e1a8efcc576607.zip
Merge pull request #9166 from robbie-hatley/robbie-hatley-245
Robbie Hatley's Perl solutions to The Weekly Challenge #245.
-rw-r--r--challenge-245/robbie-hatley/blog.txt1
-rwxr-xr-xchallenge-245/robbie-hatley/perl/ch-1.pl128
-rwxr-xr-xchallenge-245/robbie-hatley/perl/ch-2.pl139
3 files changed, 268 insertions, 0 deletions
diff --git a/challenge-245/robbie-hatley/blog.txt b/challenge-245/robbie-hatley/blog.txt
new file mode 100644
index 0000000000..d163338835
--- /dev/null
+++ b/challenge-245/robbie-hatley/blog.txt
@@ -0,0 +1 @@
+https://hatley-software.blogspot.com/2023/11/robbie-hatleys-solutions-to-weekly_29.html \ No newline at end of file
diff --git a/challenge-245/robbie-hatley/perl/ch-1.pl b/challenge-245/robbie-hatley/perl/ch-1.pl
new file mode 100755
index 0000000000..1b3c6a819a
--- /dev/null
+++ b/challenge-245/robbie-hatley/perl/ch-1.pl
@@ -0,0 +1,128 @@
+#!/usr/bin/env -S perl -CSDA
+
+=pod
+
+--------------------------------------------------------------------------------------------------------------
+COLOPHON:
+This is a 110-character-wide Unicode UTF-8 Perl-source-code text file with hard Unix line breaks ("\x0A").
+¡Hablo Español! Говорю Русский. Björt skjöldur. ॐ नमो भगवते वासुदेवाय. 看的星星,知道你是爱。麦藁雪、富士川町、山梨県。
+
+--------------------------------------------------------------------------------------------------------------
+TITLE BLOCK:
+Solutions in Perl for The Weekly Challenge 245-1.
+Written by Robbie Hatley on Tue Nov 28, 2023.
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM DESCRIPTION:
+Task 245-1: Sort Language
+Submitted by: Mohammad S Anwar
+You are given two arrays: one of languages and the other of their
+popularities. Write a script to sort the languages based on their
+popularities.
+
+Example 1:
+Input: @lang = ('perl', 'c', 'python'); @popularity = (2, 1, 3);
+Output: ('c', 'perl', 'python')
+
+Example 2:
+Input: @lang = ('c++', 'haskell', 'java'); @popularity = (1, 3, 2);
+Output: ('c++', 'java', 'haskell')
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM NOTES:
+I tried solving this problem by "zipping" the two arrays together to make an array of [language, popularity]
+pairs, then sorting that array numerically by the second elements of the pairs; however, the resulting code
+was excessively verbose. But then I hit upon a much easier way: use an array slice! Take the indexes of the
+first array (0..$#$aref1), re-order them according to a sort of the second array, then "slice" the first
+array using the re-ordered indexes. The result was that I could now solve this entire problem with half a line
+of code.
+
+--------------------------------------------------------------------------------------------------------------
+IO NOTES:
+Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a
+double-quoted array of arrays of two arrays, with the inner array pairs consisting of an array of
+single-quoted strings followed by an array of small positive integers (1-9), in proper Perl syntax, like so:
+./ch-1.pl "([['Go','Lisp','AutoIt3','Logo'],[2, 1, 4, 3]],[['Awk','Cobol','Perl','Sed'],[3,4,1,2]])"
+
+Output is to STDOUT and will be each input array followed by the corresponding output.
+
+=cut
+
+# ------------------------------------------------------------------------------------------------------------
+# PRAGMAS AND MODULES USED:
+
+use v5.38;
+use strict;
+use warnings;
+use utf8;
+use warnings FATAL => 'utf8';
+use Sys::Binmode;
+use Time::HiRes 'time';
+
+# ------------------------------------------------------------------------------------------------------------
+# START TIMER:
+our $t0;
+BEGIN {$t0 = time}
+
+# ------------------------------------------------------------------------------------------------------------
+# SUBROUTINES:
+
+sub is_array_of_pos_ints($aref) {
+ return 0 if 'ARRAY' ne ref $aref;
+ for (@$aref) {
+ return 0 if !/^[1-9]\d*$/;
+ }
+ return 1;
+}
+
+sub sort_array1_by_array2($aref1, $aref2) {
+ return @$aref1[sort{$$aref2[$a]<=>$$aref2[$b]}0..$#$aref1];
+}
+
+# ------------------------------------------------------------------------------------------------------------
+# MAIN BODY OF PROGRAM:
+
+# Inputs:
+my @arrays = @ARGV ? eval($ARGV[0]) :
+(
+ # Example 1 Inputs:
+ [
+ ['perl', 'c', 'python'],
+ [2, 1, 3],
+ ],
+ # Expected Output: ('c', 'perl', 'python')
+
+ # Example 2 Inputs:
+ [
+ ['c++', 'haskell', 'java'],
+ [1, 3, 2],
+ ],
+ # Expected Output: ('c++', 'java', 'haskell')
+);
+
+# Main loop:
+for my $aref (@arrays) {
+ say '';
+ my $aref1 = $aref->[0];
+ my $aref2 = $aref->[1];
+ say 'Languages = (' . join(', ', map {"'$_'"} @$aref1) . ')';
+ say 'Popularities = (' . join(', ', @$aref2) . ')';
+ if ( scalar(@$aref1) != scalar(@$aref2) ) {
+ say 'Error: subarrays are of unequal lengths.';
+ say 'Moving on to next array.';
+ next;
+ }
+ if ( !is_array_of_pos_ints($aref2) ) {
+ say 'Error: second subarray is not array of positive integers.';
+ say 'Moving on to next array.';
+ next;
+ }
+ my @sorted = sort_array1_by_array2($aref1, $aref2);
+ say 'Sorted = (' . join(', ', map {"'$_'"} @sorted) . ')';
+}
+exit;
+
+# ------------------------------------------------------------------------------------------------------------
+# DETERMINE AND PRINT EXECUTION TIME:
+END {my $µs = 1000000 * (time - $t0);printf("\nExecution time was %.0fµs.\n", $µs)}
+__END__
diff --git a/challenge-245/robbie-hatley/perl/ch-2.pl b/challenge-245/robbie-hatley/perl/ch-2.pl
new file mode 100755
index 0000000000..94ff417c2d
--- /dev/null
+++ b/challenge-245/robbie-hatley/perl/ch-2.pl
@@ -0,0 +1,139 @@
+#!/usr/bin/env -S perl -CSDA
+
+=pod
+
+--------------------------------------------------------------------------------------------------------------
+COLOPHON:
+This is a 110-character-wide Unicode UTF-8 Perl-source-code text file with hard Unix line breaks ("\x0A").
+¡Hablo Español! Говорю Русский. Björt skjöldur. ॐ नमो भगवते वासुदेवाय. 看的星星,知道你是爱。麦藁雪、富士川町、山梨県。
+
+--------------------------------------------------------------------------------------------------------------
+TITLE BLOCK:
+Solutions in Perl for The Weekly Challenge 245-2.
+Written by Robbie Hatley on Tue Nov 28, 2023.
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM DESCRIPTION:
+Task 245-2: Largest of Three
+Submitted by: Mohammad S Anwar
+You are given an array of integers >= 0. Write a script to return
+the largest number formed by concatenating some of the given
+integers in any order which is also multiple of 3. Return -1 if
+none found.
+
+Example 1:
+Input: @ints = (8, 1, 9)
+Output: 981
+981 % 3 == 0
+
+Example 2:
+Input: @ints = (8, 6, 7, 1, 0)
+Output: 8760
+
+Example 3:
+Input: @ints = (1)
+Output: -1
+
+--------------------------------------------------------------------------------------------------------------
+PROBLEM NOTES:
+This problem is really just a matter of combinatorics, so I'll use CPAN module "Math::Combinatorics".
+But this time I'll use it's non-OOP functions, as OOP just isn't necessary for a problem like this and just
+gets in the way. I'll call my main sub "sub largest_of_three($aref)", which will find the largest multiple of
+3 I can make by concatenting any permutation of any combination of integers from the input array, or return -1
+if I can't make any divisible-by-three integers.
+
+--------------------------------------------------------------------------------------------------------------
+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 non-negative integers, in proper Perl syntax, like so:
+./ch-2.pl '([3,14,0,5,72],[1,0,97,23])'
+
+Output is to STDOUT and will be each input array followed by the corresponding output.
+
+=cut
+
+# ------------------------------------------------------------------------------------------------------------
+# PRAGMAS AND MODULES USED:
+
+use v5.38;
+use strict;
+use warnings;
+use utf8;
+use warnings FATAL => 'utf8';
+use Sys::Binmode;
+use Time::HiRes 'time';
+use Math::Combinatorics;
+
+# ------------------------------------------------------------------------------------------------------------
+# START TIMER:
+our $t0;
+BEGIN {$t0 = time}
+
+# ------------------------------------------------------------------------------------------------------------
+# SUBROUTINES:
+
+# Are all of the elements of a referred-to array decimal representations of non-negative integers?
+sub are_nni ($aref) {
+ return 0 if 'ARRAY' ne ref $aref;
+ return 0 if scalar(@$aref) < 1;
+ for (@$aref) {return 0 if !/^0$|^[1-9]\d*$/}
+ return 1;
+}
+
+sub largest_of_three($aref) {
+ # For each possible non-empty subset size of @$aref, get all combinations
+ # of that size, then get all permutations of each of those combinations,
+ # then concatentate each of those permutations to an integer, and keep track
+ # of the maximum divisible-by-3 integer seen, then return the maximum
+ # which will be -1 if we couldn't make any divisible-by-3 integers:
+ my $max = -1;
+ for ( my $size = scalar(@$aref) ; $size >= 1 ; --$size ) {
+ my @combs = combine($size,@$aref);
+ for my $cref ( @combs ) {
+ my @perms = permute(@$cref);
+ for my $pref ( @perms ) {
+ my $integer = join('',@$pref);
+ 0 == $integer % 3 && $integer > $max and $max = $integer;
+ }
+ }
+ }
+ return $max;
+}
+
+# ------------------------------------------------------------------------------------------------------------
+# MAIN BODY OF PROGRAM:
+
+# Inputs:
+my @arrays = @ARGV ? eval($ARGV[0]) :
+(
+ # Example 1 Input:
+ [8, 1, 9],
+ # Expected Output: 981
+
+ # Example 2 Input:
+ [8, 6, 7, 1, 0],
+ # Expected Output: 8760
+
+ # Example 3 Input:
+ [1],
+ # Expected Output: -1
+);
+
+# Main loop:
+for my $aref (@arrays) {
+ say '';
+ say 'Array = (' . join(', ', @$aref) . ')';
+ if ( !are_nni($aref) ) {
+ say 'Error: not an array of non-negative integers.';
+ say 'Moving on to next array.';
+ next;
+ }
+ say 'Greatest multiple of 3 creatable from array = ',
+ largest_of_three($aref);
+}
+exit;
+
+# ------------------------------------------------------------------------------------------------------------
+# DETERMINE AND PRINT EXECUTION TIME:
+END {my $µs = 1000000 * (time - $t0);printf("\nExecution time was %.0fµs.\n", $µs)}
+__END__