diff options
| author | Matthew Neleigh <matthew.neleigh@gmail.com> | 2023-04-02 03:19:13 -0400 |
|---|---|---|
| committer | Matthew Neleigh <matthew.neleigh@gmail.com> | 2023-04-02 03:19:13 -0400 |
| commit | a039f6ab34716e4a36d7748ee90f8591efacfb05 (patch) | |
| tree | e219110af07aacef90af9f237974513d6bb0b550 | |
| parent | 8915a66de2cb2a724aee5e55ddfc15580cfdf1d5 (diff) | |
| download | perlweeklychallenge-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-x | challenge-210/mattneleigh/perl/ch-1.pl | 114 | ||||
| -rwxr-xr-x | challenge-210/mattneleigh/perl/ch-2.pl | 86 |
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); + +} + + + |
