aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-08-27 13:28:29 +0100
committerGitHub <noreply@github.com>2021-08-27 13:28:29 +0100
commit6ad924c879ed308d18c53eb87eaf83a22fb8d580 (patch)
tree20845dd423eb15a5480c08375ceb931ddbd30caf
parent3187e2b43acdc234183ec708393214338bc7d234 (diff)
parent6b9e44aa643f6aad6fdfb80360c5a4f3a339cf31 (diff)
downloadperlweeklychallenge-club-6ad924c879ed308d18c53eb87eaf83a22fb8d580.tar.gz
perlweeklychallenge-club-6ad924c879ed308d18c53eb87eaf83a22fb8d580.tar.bz2
perlweeklychallenge-club-6ad924c879ed308d18c53eb87eaf83a22fb8d580.zip
Merge pull request #4794 from mattneleigh/pwc127
new file: challenge-127/mattneleigh/perl/ch-1.pl
-rwxr-xr-xchallenge-127/mattneleigh/perl/ch-1.pl98
-rwxr-xr-xchallenge-127/mattneleigh/perl/ch-2.pl135
2 files changed, 233 insertions, 0 deletions
diff --git a/challenge-127/mattneleigh/perl/ch-1.pl b/challenge-127/mattneleigh/perl/ch-1.pl
new file mode 100755
index 0000000000..61de6e0bfc
--- /dev/null
+++ b/challenge-127/mattneleigh/perl/ch-1.pl
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @sets = (
+ [
+ [ 1, 2, 5, 3, 4 ],
+ [ 4, 6, 7, 8, 9 ]
+ ],
+ [
+ [ 1, 3, 5, 7, 9 ],
+ [ 0, 2, 4, 6, 8 ]
+ ],
+ [
+ # I'm just being cheeky here, but this
+ # demonstrates how my solution behaves
+ # with non-integer input and provides
+ # an instance in which multiple
+ # members of S2 are found in S1
+ [ qw(Perl and UNIX are awesome) ],
+ [ qw(Let's write some awesome code in Perl) ]
+ ]
+);
+my $pair;
+my @common;
+
+foreach $pair (@sets){
+ printf("Input: \@S1 = (%s)\n", join(", ", @{$pair->[0]}));
+ printf(" \@S2 = (%s)\n", join(", ", @{$pair->[1]}));
+
+ @common = sets_disjoint($pair->[0], $pair->[1]);
+
+ if(scalar(@common)){
+ # There were common members
+ printf(
+ "Output: 0 as the given two sets have common member(s): %s.\n",
+ join(", ", @common)
+ );
+ } else{
+ # There were no common members
+ print(
+ "Output: 1 as the given two sets do not have a common member.\n"
+ );
+ }
+ print("\n");
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Determine if two sets are disjoint, or if not, which members they have in
+# common; this will work for any two sets of scalar values that can be used as
+# hash keys, but note that string matching will be case-sensitive
+# Takes two arguments:
+# * A ref to an array whose values form the members of Set 1
+# * A ref to an array whose values form the members of Set 2
+# Returns:
+# * A list of values common to the two sets, in the order in which they appear
+# in Set 2; if this list is empty, the sets are disjoint (no common members)
+################################################################################
+sub sets_disjoint{
+ my $set1 = shift();
+ my $set2 = shift();
+
+ my %set1_lookup;
+ my @common_members = ();
+
+ # Map Set 1 to a hash, storing a true
+ # value for each member of the set,
+ # using said members as the keys
+ %set1_lookup = map({ $_ => 1 } @{$set1});
+
+ foreach(@{$set2}){
+ # Loop over Set 2, adding the value
+ # to the common members list if a
+ # true value is found in the lookup
+ # hash, which would indicate that
+ # this value was also found in Set 1
+ push(@common_members, $_) if($set1_lookup{$_});
+ }
+
+ # Return the list to the caller
+ return(@common_members);
+
+}
+
+
+
diff --git a/challenge-127/mattneleigh/perl/ch-2.pl b/challenge-127/mattneleigh/perl/ch-2.pl
new file mode 100755
index 0000000000..68d42d8b47
--- /dev/null
+++ b/challenge-127/mattneleigh/perl/ch-2.pl
@@ -0,0 +1,135 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @inputs = (
+ [ [1, 4], [3, 5], [6, 8], [12, 13], [3, 20] ],
+ [ [3, 4], [5, 7], [6, 9], [10, 12], [13, 15] ]
+);
+my $intervals;
+my @overlaps;
+my @strings;
+
+foreach $intervals (@inputs){
+ @strings = ();
+
+ # Complicated output with nested
+ # comma-separated lists...
+ printf(
+ "Input: \@Intervals = [ %s ]\n",
+ join(
+ ", ",
+ map(
+ { sprintf("(%s)", join(", ", @{$_})); }
+ @{$intervals}
+ )
+ )
+ );
+
+ @overlaps = find_previous_overlaps(@{$intervals});
+
+ # Even more complicated output with
+ # nested comma-separated lists...
+ # for-loop because we need to know
+ # where in the list we are when we
+ # find something
+ for my $i (0 .. $#overlaps){
+ # We don't actually care what the
+ # overlaps are in this case- it's
+ # enough to know which intervals
+ # have them
+ if(scalar(@{$overlaps[$i]})){
+ push(
+ @strings,
+ sprintf("(%s)", join(", ", @{$intervals->[$i]}))
+ );
+ }
+ }
+ printf("Output: [ %s ]\n", join(", ", @strings));
+
+ print("\n");
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Find overlaps between numerical intervals in a list and previous (but not
+# subsequent) intervals within that list
+# Takes one argument:
+# * A list of refs to intervals- arrays containing two numerical values, which
+# must appear in ascending order (e.g. [1, 5] but not [7, 3])
+# Returns:
+# * A list of refs to arrays containing the indices of overlapping intervals
+# found earlier in the original interval list; the position of each array in
+# this list corresponds to the position of the member of the argument list
+# that was being checked for previous overlaps. If no overlaps were found
+# for that interval, the corresponding array in the returned list will be
+# empty. As there are no previous arguments to check for the first interval,
+# the first returned array will always be empty.
+#
+# Example:
+# @intervals = ( [3, 5], [7, 10], [6, 8], [4, 9] );
+# @overlaps = find_previous_overlaps(@intervals);
+# # @overlaps contains:
+# # ( [], [], [ 1 ], [ 0, 1, 2 ] )
+#
+################################################################################
+sub find_previous_overlaps{
+
+ my $i;
+ my $j;
+ my $overlap_intervals;
+ my @return_intervals;
+
+ # Add an empty list for the 0th interval
+ # as it can't overlap with any previous one
+ @return_intervals = ( [] );
+
+ # Loop over intervals from the 1th (as
+ # opposed to the 1st) onward
+ for $i (1 .. $#ARG){
+ $overlap_intervals = [];
+
+ # Loop over intervals from the 0th to the
+ # (i - 1)th
+ for $j (0 .. ($i - 1)){
+ # Basically:
+ # if(max(beginnings) - min(ends) <= 0)
+ if(
+ # Maximum of the beginnings of the ranges
+ ($ARG[$j][0] > $ARG[$i][0] ? $ARG[$j][0] : $ARG[$i][0])
+ -
+ # Minimum of the ends of the ranges
+ ($ARG[$j][1] < $ARG[$i][1] ? $ARG[$j][1] : $ARG[$i][1])
+ <=
+ 0
+ ){
+ # The jth interval overlaps with the
+ # ith- store j
+ push(@{$overlap_intervals}, $j);
+ }
+ }
+
+ # Store the list of intervals that
+ # overlapped with the ith, empty or
+ # not
+ push(@return_intervals, $overlap_intervals);
+ }
+
+ return(@return_intervals);
+
+}
+
+
+