diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-08-27 13:28:29 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-27 13:28:29 +0100 |
| commit | 6ad924c879ed308d18c53eb87eaf83a22fb8d580 (patch) | |
| tree | 20845dd423eb15a5480c08375ceb931ddbd30caf | |
| parent | 3187e2b43acdc234183ec708393214338bc7d234 (diff) | |
| parent | 6b9e44aa643f6aad6fdfb80360c5a4f3a339cf31 (diff) | |
| download | perlweeklychallenge-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-x | challenge-127/mattneleigh/perl/ch-1.pl | 98 | ||||
| -rwxr-xr-x | challenge-127/mattneleigh/perl/ch-2.pl | 135 |
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); + +} + + + |
