aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsouthpawgeek <jen@southpawgeek.com>2020-03-08 15:30:10 -0400
committersouthpawgeek <jen@southpawgeek.com>2020-03-08 15:30:10 -0400
commitfe1160c8c7c0b2efb26cb8a43d32ba20b68c1b3a (patch)
tree429fbde1239b2f2f94a7db0b7c983f377b978826
parent62e6f8544e7bdba17cee267f2911574527bdd1e6 (diff)
downloadperlweeklychallenge-club-fe1160c8c7c0b2efb26cb8a43d32ba20b68c1b3a.tar.gz
perlweeklychallenge-club-fe1160c8c7c0b2efb26cb8a43d32ba20b68c1b3a.tar.bz2
perlweeklychallenge-club-fe1160c8c7c0b2efb26cb8a43d32ba20b68c1b3a.zip
reworked interval merge
-rw-r--r--challenge-050/southpawgeek/perl/ch-1.pl97
1 files changed, 97 insertions, 0 deletions
diff --git a/challenge-050/southpawgeek/perl/ch-1.pl b/challenge-050/southpawgeek/perl/ch-1.pl
index e69de29bb2..6500a109ac 100644
--- a/challenge-050/southpawgeek/perl/ch-1.pl
+++ b/challenge-050/southpawgeek/perl/ch-1.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use feature qw/say/;
+
+my @sets = (
+ # given set
+ ['[2,7]', '[3,9]', '[10,12]', '[15,19]', '[18,22]'],
+
+ # given set in reverse
+ ['[18,22]', '[15,19]', '[10,12]', '[3,9]', '[2,7]'],
+
+ # out of order, overlapping lo vals, negatives
+ ['[1,9]', '[8,12]', '[15,23]', '[1,8]', '[-9,-3]'],
+
+ # out of order, negatives, zero val
+ ['[9,3]', '[4,12]', '[0,99]', '[-3,-1]'],
+
+ # just one set
+ ['[0,1]']
+ );
+
+merge($_) foreach @sets;
+
+sub merge {
+ my $set = shift;
+ say "-"x25;
+ say "@$set is the given set. \n";
+
+ # remove all brackets and commas
+ my @ints = "@$set" =~ /(-?\d+)/g;
+
+ my %no_same_lo;
+ while (@ints) {
+ # process in pairs
+ my $lo = shift @ints;
+ my $hi = shift @ints;
+
+ # what if interval was [hi,lo] by accident?
+ ($lo, $hi) = ($hi, $lo) if $lo > $hi;
+
+ # what if multiple intervals have the same lo?
+ # we only care about the highest hi val here
+ $no_same_lo{$lo} = $hi
+ unless defined($no_same_lo{$lo} && $no_same_lo{$lo} <= $hi);
+ }
+
+ # what if given intervals weren't in order?
+ foreach my $lo (sort {$a <=> $b} keys %no_same_lo) {
+ push @ints, ($lo, $no_same_lo{$lo});
+ }
+
+ # now we're sorted, removed duplicate lows, and fixed transpositions
+ # if there's only one set [x,y] we're done
+ # given [x,y], [z,w]: if y > z we can merge, if not move on
+
+ my @merged;
+ my ($lo, $hi);
+ while (scalar @ints) {
+ # pull next 2 values
+ $lo = shift @ints;
+ $hi = shift @ints;
+
+ # only compare if there's more in the array
+ if (scalar @ints) {
+ # grab another 2 values
+ my $nextlo = shift @ints;
+ my $nexthi = shift @ints;
+ say "[$lo,$hi] -> [$nextlo,$nexthi]";
+
+ if ($hi >= $nextlo) {
+ # we can merge
+ # but check the two hi values first
+ $nexthi = $hi if $hi > $nexthi;
+ say "[$lo,$nexthi] is the NEW merged interval.";
+
+ # put new set back into the front of the array
+ unshift @ints, ($lo, $nexthi);
+ $hi = $nexthi;
+
+ } else {
+ # can't merge, add to final set
+ say "[$lo, $hi] can't be merged. Moving to final set.\n";
+ push @merged, "[$lo,$hi]";
+
+ # but put set back into the array
+ unshift @ints, ($nextlo, $nexthi);
+ }
+ } else {
+ # we're done here
+ say "[$lo,$hi] is the last pair. Moving to final set.\n";
+ push @merged, "[$lo,$hi]";
+ }
+ }
+
+ say "@merged is the merged set. \n";
+} \ No newline at end of file