diff options
| author | robbie-hatley <Robbie.Hatley@gmail.com> | 2023-04-03 21:05:13 -0700 |
|---|---|---|
| committer | robbie-hatley <Robbie.Hatley@gmail.com> | 2023-04-03 21:05:13 -0700 |
| commit | 8ab37815f55b019f73272256613e2e432fa0da7c (patch) | |
| tree | 5eb651008c223630565a8016024682001556a878 | |
| parent | ed17a0bef83e3276a3949814dab37a8a51871041 (diff) | |
| download | perlweeklychallenge-club-8ab37815f55b019f73272256613e2e432fa0da7c.tar.gz perlweeklychallenge-club-8ab37815f55b019f73272256613e2e432fa0da7c.tar.bz2 perlweeklychallenge-club-8ab37815f55b019f73272256613e2e432fa0da7c.zip | |
Robbie Hatley's Perl solutions to The Weekly Challenge 211
| -rw-r--r-- | challenge-211/robbie-hatley/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-211/robbie-hatley/ch-1.pl | 90 | ||||
| -rwxr-xr-x | challenge-211/robbie-hatley/ch-2.pl | 118 |
3 files changed, 209 insertions, 0 deletions
diff --git a/challenge-211/robbie-hatley/blog.txt b/challenge-211/robbie-hatley/blog.txt new file mode 100644 index 0000000000..03447b9b02 --- /dev/null +++ b/challenge-211/robbie-hatley/blog.txt @@ -0,0 +1 @@ +https://hatley-software.blogspot.com/2023/04/robbie-hatleys-perl-solutions-to-weekly.html
\ No newline at end of file diff --git a/challenge-211/robbie-hatley/ch-1.pl b/challenge-211/robbie-hatley/ch-1.pl new file mode 100755 index 0000000000..be58407553 --- /dev/null +++ b/challenge-211/robbie-hatley/ch-1.pl @@ -0,0 +1,90 @@ +#! /bin/perl +# Robbie Hatley's Perl solutions to The Weekly Challenge #211-1 + +# ====================================================================== +# PROBLEM DESCRIPTION: + +=pod + +Task 1: Toeplitz Matrix +Submitted by: Mohammad S Anwar +You are given a matrix m x n. Write a script to find out if the given +matrix is Toeplitz Matrix. A matrix is Toeplitz if every diagonal from +top-left to bottom-right has the same elements. + +Example 1: +Input: [[4, 3, 2, 1], [5, 4, 3, 2], [6, 5, 4, 3]] +Output: true + +Example 2: +Input: [[1, 2, 3], [3, 2, 1]] +Output: false + +=cut + +# ====================================================================== +# INPUT / OUTPUT NOTES: +# Input is from built-in array-of-arrays or from @ARGV. If using @ARGV, +# input should be one 'single-quoted' string expressing an array of +# arrays of arrays of integers in valid Perl syntax, with each array +# containing only arrays of the same size, like so: +# ./ch-1.pl '([[1,2],[2,3]], [[1,3,5],[3,5,1],[5,1,3]])' +# +# Output is to STDOUT and will be the input array followed by +# "Matrix IS Toeplitz" or "Matrix is NOT Toeplitz" + +# ====================================================================== +# PRELIMINARIES: +use v5.36; +use strict; +use warnings; + +# ====================================================================== +# SUBROUTINES: + +# Say whether-or-not a referred-to rectangular 2-d matrix is Toeplitz, +# without altering the original matrix: +sub is_toeplitz($mref){ + # Make a deep copy of @$aref (simple copy is NOT deep copy!!!): + my $height = scalar(@$mref); + my $width = scalar(@{$mref->[0]}); + say "Height = $height"; + say "Width = $width"; + # Test length 2+ diagonals starting from top: + for ( my $i = 0 ; $i <= $width-2 ; ++$i ){ + for ( my $j = $i+1, my $k = 1 ; $j < $width && $k < $height ; ++$j, ++$k ){ + return 0 if $mref->[$k]->[$j] != $mref->[0]->[$i]; + } + } + # Test length 2+ diagonals starting from left: + for ( my $i = 1 ; $i <= $height-2 ; ++$i ){ + for ( my $j = 1, my $k = $i+1 ; $j < $width && $k < $height ; ++$j, ++$k ){ + return 0 if $mref->[$k]->[$j] != $mref->[$i]->[0]; + } + } + return 1; +} + +# ====================================================================== +# DEFAULT INPUTS: +my @matrices = +( + [[4, 3, 2, 1], [5, 4, 3, 2], [6, 5, 4, 3]], + [[1, 2, 3], [3, 2, 1]], + [[1,2],[2,1]], + [[1,3,5],[3,5,1],[5,1,3]], + [[1,5],[4,1],[2,4]], +); + +# ====================================================================== +# NON-DEFAULT INPUTS: +if (@ARGV) {@matrices = eval($ARGV[0])} + +# ====================================================================== +# MAIN BODY OF SCRIPT: +for my $matrix (@matrices){ + say ''; + say 'Matrix:'; + say "@$_" for @$matrix; + say is_toeplitz($matrix) ? "Matrix IS Toeplitz" : "Matrix is NOT Toeplitz"; +} diff --git a/challenge-211/robbie-hatley/ch-2.pl b/challenge-211/robbie-hatley/ch-2.pl new file mode 100755 index 0000000000..13325d3912 --- /dev/null +++ b/challenge-211/robbie-hatley/ch-2.pl @@ -0,0 +1,118 @@ +#! /bin/perl +# Robbie Hatley's Perl solutions to The Weekly Challenge #211-2 + +# ====================================================================== +# PROBLEM DESCRIPTION: + +=pod + +Task 2: Split Same Average +Submitted by: Mohammad S Anwar +You are given an array of integers. Write a script to find out if the +given can be split into two separate arrays whose average are the same. + +Example 1: Input=(1, 2, 3, 4, 5, 6, 7, 8) Output=true +Example 2: Input=(1, 3) Output=false + +=cut + +# ====================================================================== +# INPUT / OUTPUT NOTES: +# Input is from built-in array-of-arrays or from @ARGV. If using @ARGV, +# input should be one 'single-quoted' string expressing an array of +# arrays of integers in valid Perl syntax. +# +# Output is to STDOUT and will be input array followed by either +# a split with equal averages or a notice that no such split exists. + +# ====================================================================== +# PRELIMINARIES: +use v5.36; +use strict; +use warnings; +use Set::Partition; +use List::AllUtils 'sum0'; +$"=', '; + +# ====================================================================== +# VARIABLES: +my $db = 0; # Debug? + +# ====================================================================== +# SUBROUTINES: + +# Obtain an array of all partitions of a given set into two non-empty +# parts with the size of the first part not-greater-than the size of the +# second part (to avoid duplicate partitions): +sub two_non_empty ($aref, $partref){ + # How big is the original array? + my $size = scalar(@{$aref}); + # No need to allow the first part to be more than half the size + # of the array, else we'd get duplicate partitions: + my $limit = int($size/2); + for ( my $n = 1 ; $n <= $limit ; ++$n ){ + my $parts = Set::Partition->new( + list => $aref, + partition => [$n, $size - $n], + ); + while (my $part = $parts->next) { + push @{$partref}, $part; + } + } +} + +# What is the average of the real numbers in a referred-to array? +sub average ($aref) {return sum0(@$aref)/scalar(@$aref);} + +# Are two floating-point numbers "equal" to within one millionth? +sub equal ($x, $y) {abs($x-$y) < 0.000001 ? return 1 : return 0;} + +# ====================================================================== +# DEFAULT INPUTS: +my @arrays = +( + [1, 2, 3, 4, 5, 6, 7, 8], + [1, 3], + [3, 6, -2.3, 8.64, 5.36], + [3, 6, -2, 8, 5], + [4, 6, 8, 9] +); + +# ====================================================================== +# NON-DEFAULT INPUTS: +if (@ARGV) {@arrays = eval($ARGV[0])} + +# ====================================================================== +# MAIN BODY OF SCRIPT: + +ARRAY: for (@arrays){ + say ''; + say "array = (@$_)"; + my $partitions = []; + two_non_empty($_, $partitions); + my $equal_average_flag = 0; + # If debugging, print lots of extra diagnostics: + if ($db) { + say 'Partitions:'; + for (@$partitions){ + my $a1 = average($_->[0]); + my $a2 = average($_->[1]); + my $e = equal($a1, $a2) ? 'EQUAL!!!' : ''; + say("(@{$_->[0]}) (@{$_->[1]}) $a1 $a2 $e"); + } + } + # Otherwise, just print the basics: + else { + for (@$partitions){ + my $a1 = average($_->[0]); + my $a2 = average($_->[1]); + if (equal($a1, $a2)) { + say 'array can be split into ' + . "(@{$_->[0]}) and (@{$_->[1]}), " + . "both with average $a1"; + next ARRAY; + } + } + say 'No equal-average split exists.'; + } +} |
