aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Neleigh <matthew.neleigh@gmail.com>2023-04-02 03:19:13 -0400
committerMatthew Neleigh <matthew.neleigh@gmail.com>2023-04-02 03:19:13 -0400
commita039f6ab34716e4a36d7748ee90f8591efacfb05 (patch)
treee219110af07aacef90af9f237974513d6bb0b550
parent8915a66de2cb2a724aee5e55ddfc15580cfdf1d5 (diff)
downloadperlweeklychallenge-club-a039f6ab34716e4a36d7748ee90f8591efacfb05.tar.gz
perlweeklychallenge-club-a039f6ab34716e4a36d7748ee90f8591efacfb05.tar.bz2
perlweeklychallenge-club-a039f6ab34716e4a36d7748ee90f8591efacfb05.zip
new file: challenge-210/mattneleigh/perl/ch-1.pl
new file: challenge-210/mattneleigh/perl/ch-2.pl
-rwxr-xr-xchallenge-210/mattneleigh/perl/ch-1.pl114
-rwxr-xr-xchallenge-210/mattneleigh/perl/ch-2.pl86
2 files changed, 200 insertions, 0 deletions
diff --git a/challenge-210/mattneleigh/perl/ch-1.pl b/challenge-210/mattneleigh/perl/ch-1.pl
new file mode 100755
index 0000000000..c303ce4ebb
--- /dev/null
+++ b/challenge-210/mattneleigh/perl/ch-1.pl
@@ -0,0 +1,114 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @integer_lists = (
+ # Given cases
+ [ 2, 3, 1 ],
+ [ 1, 1, 2, 2, 2, 3 ],
+
+ # Additional test cases
+ [ 1, 1, 2, 2, 2, 2, 2, 2, 3, 4 ],
+ [ 1, 1, 1, 5, 5, 5, 5, 6, 7, 8 ],
+ [ 1, 1, 5, 5, 5, 5, 7, 7, 7, 9 ],
+);
+
+print("\n");
+foreach my $list (@integer_lists){
+ printf(
+ "Input: \@int = (%s)\nOutput: %d\nAfter deletions: (%s)\n\n",
+ join(", ", @{$list}),
+ maximum_deletion_score($list),
+ join(", ", @{$list})
+ );
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Delete integers from a list, so as to maximize the sum of the integers
+# removed. All instances of one integer, all instances of that integer minus
+# one, if present, and all instances of that integer plus one, if present,
+# will be removed (e.g. 3, 2, and 4, respectively).
+# Takes one argument:
+# * A ref to the list of integers to process (e.g.
+# [ 1, 1, 2, 2, 2, 2, 2, 2, 3, 4 ] )
+# Returns:
+# * The total of all the integers removed from the list (e.g. 19 as 3 would be
+# chosen as the number to delete, as well as 2 and 4)
+# NOTE: THE LIST WILL BE MODIFIED AS APPROPRIATE INTEGERS ARE DELETED FROM IT;
+# the list need not be sorted when provided, but will be sorted after deletions
+# are complete (e.g. the list above will be reduced to [ 1, 1 ] )
+################################################################################
+sub maximum_deletion_score{
+ use List::Util qw(min max);
+
+ my $n;
+ my %subtotals;
+ my $selection;
+ my $max_total = 0;
+
+ # Use each integer as a key in the subtotals
+ # hash, adding up the sum of all instances of
+ # each
+ while(defined($n = shift(@{$ARG[0]}))){
+ if(defined($subtotals{$n})){
+ $subtotals{$n} += $n;
+ } else{
+ $subtotals{$n} = $n;
+ }
+ }
+
+ # Loop over the observed integers, to find the
+ # maximum of the totals of each number AND the
+ # values one above and one below, if present
+ for $n (keys(%subtotals)){
+ my $total = (
+ (defined($subtotals{$n}) ? $subtotals{$n} : 0)
+ +
+ (defined($subtotals{$n - 1}) ? $subtotals{$n - 1} : 0)
+ +
+ (defined($subtotals{$n + 1}) ? $subtotals{$n + 1} : 0)
+ );
+
+ if($total > $max_total){
+ $selection = $n;
+ $max_total = $total;
+ }
+ }
+
+ # Delete our selected value and the values one
+ # above and one below from the set of observed
+ # integers
+ for $n ($selection - 1 .. $selection + 1){
+ delete($subtotals{$n});
+ }
+
+ # Replace the original list with one made up
+ # only of the remaining integers- in the
+ # correct quantities originally observed
+ foreach $n (sort(keys(%subtotals))){
+ push(
+ @{$ARG[0]},
+ map($n, (1 .. ($subtotals{$n} / $n)))
+ );
+ delete($subtotals{$n});
+ }
+
+ return($max_total);
+
+}
+
+
+
diff --git a/challenge-210/mattneleigh/perl/ch-2.pl b/challenge-210/mattneleigh/perl/ch-2.pl
new file mode 100755
index 0000000000..0cb098c9ec
--- /dev/null
+++ b/challenge-210/mattneleigh/perl/ch-2.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @integer_lists = (
+ # Given cases
+ [ 2, 3, -1 ],
+ [ 3, 2, -4 ],
+ [ 1, -1 ],
+
+ # Additional test cases
+ [ -3, 2 ],
+ [ 1, 0, 4, -1, 2, -3, 3 ],
+ [ 10, 1, 3, 3, 4, 5, 6, 7, 8, -9 ]
+);
+
+print("\n");
+foreach my $list (@integer_lists){
+ printf(
+ "Input: \@list = (%s)\nOutput: (%s)\n\n",
+ join(", ", @{$list}),
+ join(", ", move_and_collide(@{$list}))
+ );
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Given a list of integers, move positive ones to the right, and negative ones
+# to the left. Where integers heading in opposite directions meet, they will
+# collide and the one with the larger absolute value will survive; if both have
+# the same absolute value, both will be destroyed.
+# Takes one argument:
+# * A list of integers to process
+# Returns
+# * The list of integers after all movement and collisions are resolved
+################################################################################
+sub move_and_collide{
+
+ my $collision = 1;
+
+ while($collision){
+ my $i = 0;
+
+ $collision = 0;
+ while($i < $#ARG){
+ if($ARG[$i + 1] < 0){
+ # The next number wants to move
+ # left
+ if(abs($ARG[$i]) < abs($ARG[$i + 1])){
+ # The current number explodes
+ splice(@ARG, $i, 1);
+ } elsif(abs($ARG[$i]) > abs($ARG[$i + 1])){
+ # The next number explodes
+ splice(@ARG, $i + 1, 1);
+ } else{
+ # Both explode
+ splice(@ARG, $i, 2);
+ }
+
+ $collision = 1;
+ } else{
+ # No collision- move on to the next
+ # number
+ $i++;
+ }
+ }
+ }
+
+ return(@ARG);
+
+}
+
+
+