diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2023-04-03 00:40:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-03 00:40:08 +0100 |
| commit | 7fd0d9c2ba3ec36018ddeb84377e2deda1c36d56 (patch) | |
| tree | 82c53a2e89c405701854375884d7bfbb73dde676 | |
| parent | 7783ecfe21fbc9bfa8e20c218b03c1266fec3c5a (diff) | |
| parent | 919379dab5635275f741a6099b18dec457ecb9ac (diff) | |
| download | perlweeklychallenge-club-7fd0d9c2ba3ec36018ddeb84377e2deda1c36d56.tar.gz perlweeklychallenge-club-7fd0d9c2ba3ec36018ddeb84377e2deda1c36d56.tar.bz2 perlweeklychallenge-club-7fd0d9c2ba3ec36018ddeb84377e2deda1c36d56.zip | |
Merge pull request #7823 from robbie-hatley/210
Robbie Hatley's Perl Solutions for The Weekly Challenge 210
| -rw-r--r-- | challenge-210/robbie-hatley/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-210/robbie-hatley/perl/ch-1.pl | 102 | ||||
| -rwxr-xr-x | challenge-210/robbie-hatley/perl/ch-2.pl | 121 |
3 files changed, 224 insertions, 0 deletions
diff --git a/challenge-210/robbie-hatley/blog.txt b/challenge-210/robbie-hatley/blog.txt new file mode 100644 index 0000000000..2e37320b55 --- /dev/null +++ b/challenge-210/robbie-hatley/blog.txt @@ -0,0 +1 @@ +https://hatley-software.blogspot.com/2023/03/robbie-hatleys-perl-solutions-to-weekly_29.html
\ No newline at end of file diff --git a/challenge-210/robbie-hatley/perl/ch-1.pl b/challenge-210/robbie-hatley/perl/ch-1.pl new file mode 100755 index 0000000000..2c84a11137 --- /dev/null +++ b/challenge-210/robbie-hatley/perl/ch-1.pl @@ -0,0 +1,102 @@ +#! /bin/perl + +######################################################################## +# Robbie Hatley's Perl solution to The Weekly Challenge 210-1 # +# Written 2023-03-29 by Robbie Hatley. # +######################################################################## + +use v5.32; +use strict; +use warnings; +use List::Util 'sum0'; + +=pod + +PROBLEM DESCRIPTION: + +Task 1: Kill and Win +Submitted by: Mohammad S Anwar +You are given a list of integers. + +Write a script to get the maximum "points" possible from "taking out" +or "killing" (removing) integers from a list. For each integer you +remove, all integers exactly one-less or one-more will also be removed. +The "points" will be the total of integers removed. What integers +should you remove to get maximum points? + +Example 1: Input: (2, 3, 1) Output: 6 +Example 2: Input: (1, 1, 2, 2, 2, 3) Output: 11 + +NOTE RH 2023-03-29: Since one is allowed to remove (or NOT remove) +any integers one wants to, and since the "points" is the sum of +all integers removed, the "maximum points" will always be the sum +of the positive integers (if any) in the list. One should never +remove zeros (might reduce score and can't help) or negative integers +(will always reduce score). + +summation of the sequence, or "sum0" +from the "List::Util" module. + +INPUT / OUTPUT NOTES: + +Input is from built-in array of arrays, or from @ARGV. If using @ARGV, +input should be an array of arrays of integers in proper Perl syntax, +surrounded by 'single quotes', like so: +./ch-1.pl '([-7,-1,0,12,-13],[-4,0,8,7,14])' + +Output will be to STDOUT and will be "maximum points". + +=cut + +# DEFAULT INPUTS: +my @arrays = +( + [2,3,1], + [1,1,2,2,2,3], + [-7,-1,0,12,-13], + [-4,0,8,1,7,14] +); + +# NON-DEFAULT INPUTS: +if (@ARGV) {@arrays = eval($ARGV[0])} + +# MAIN BODY OF SCRIPT: +say ''; +say 'Let the integer killings begin.'; +for (@arrays){ + + # Announce original integer list: + say ''; + say "Integer list: (@$_)"; + + # Remove all positive integers from list, but take note if we remove + # any 1s: + my @removed = (); + my $one = 0; + for ( my $i = 0 ; $i <= $#$_ ; ++$i ){ + if ( $_->[$i] > 0 ){ + if ( $_->[$i] == 1 ){$one = 1;} + push @removed, splice @$_, $i, 1; + --$i; + } + } + + # If we DID remove any 1s, also remove all zeros, because of the + # "manually removing any number x automatically removes all x-1 + # and x+1" rule: + if ( $one ){ + for ( my $i = 0 ; $i <= $#$_ ; ++$i ){ + if ( $_->[$i] == 0 ){ + push @removed, splice @$_, $i, 1; + --$i; + } + } + } + + # Announce numbers removed and remnants of original array: + say "Removed: (@removed)"; + say "Remaining: (@$_)"; + + # Calculate and announce final score: + say "Max points: ", sum0(@removed); +} diff --git a/challenge-210/robbie-hatley/perl/ch-2.pl b/challenge-210/robbie-hatley/perl/ch-2.pl new file mode 100755 index 0000000000..9264c393c6 --- /dev/null +++ b/challenge-210/robbie-hatley/perl/ch-2.pl @@ -0,0 +1,121 @@ +#! /bin/perl + +######################################################################## +# Robbie Hatley's Perl solution to The Weekly Challenge 210-2 # +# Written 2023-03-29 by Robbie Hatley. # +######################################################################## + +=pod + +PROBLEM DESCRIPTION: + +Task 2: Number Collision +Submitted by: Mohammad S Anwar +You are given an array of integers which can move to the right if they +are positive or to the left if they are negative. If two of these +integers collide, then the one with the smaller absolute value will +explode. If both have same absolute value, then they both explode. +All numbers move at the same speed, therefore any 2 numbers moving in +the same direction will never collide. Write a script to find out who +survives the collision. +Example 1: Input: (2, 3, -1) Output: (2, 3) +Example 2: Input: (3, 2, -4) Output: (-4) +Example 3: Input: (1, -1) Output: () + +NOTE RH 2023-03-29: If one-or-more zeros are present, then one has to +make some assumptions, because the rules don't specify what to do about +zeros. After thinking about it, I realized there are (at least) 15 +different ways to interpret 0. Firstly, are they left-moving, +stationary, or right-moving? And for each of those, when they collide, +do they ghost, block, destroy other, destroy self, or destroy both? +That's 3x5=15 possibilities. + +For my solution I'll assume that zeros are "moving rightward", because +the rules say "all numbers move at same speed", and speed is absolute +value of velocity, so zeros must move at either +v or -v. Because zeros +are conceptually closer to being positive than negative (because +"natural numbers" includes zero and positive integers, but not negative +integers), I'll assume +v. + +I'll also assume that zeros "collide" rather than "ghost" or "block" +when they come into contact with other numbers, because the rules +mention only "collision" as a possible way for these integers to +interact. + +I'll also assume: +0 + 0 => both explode, because equal absolute value +0 + positive => 0 explodes because it has less abs. val. +0 + negative => 0 explodes because it has less abs. val. + +I think I'll torture a 3-part loop into doing what I want: +Start at 1 and see if previous+current will collide. +If destroy current only, splice and backtrack 1. +If destroy previous or both, splice and backtrack 2. +++$i at top of loop and keep looping while $i <= $#_ . + +INPUT / OUTPUT NOTES: + +Input is from built-in array of arrays, or from @ARGV. If using @ARGV, +input should be an array of arrays of integers in proper Perl syntax, +surrounded by 'single quotes', like so: +./ch-1.pl '([-7,-6,0,12,-13],[-4,0,14,6,-7])' + +Output will be to STDOUT and will be "surviving integers". + +=cut + +# PRELIMINARIES: +use v5.32; +use strict; +use warnings; +use List::Util 'sum0'; + +# DEFAULT INPUTS: +my @arrays = +( + [2,3,-1], + [3,2,-4], + [1,-1], + [-7,-6,0,12,-13], + [-4,0,14,6,-7] +); + +# NON-DEFAULT INPUTS: +if (@ARGV) {@arrays = eval($ARGV[0])} + +# MAIN BODY OF SCRIPT: +say ''; +say 'Let the integer collisions commence.'; +for (@arrays){ + # Announce original integer list: + say ''; + say "Integer list: (@$_)"; + + # Riffle through the list, generally going from left to right, but + # backtracking as necessary to chase "sinking" negatives and process + # their collisions: + for ( my $i = 1 ; $i <= $#$_ ; ++$i ){ + next if $i < 1; # This may happen if we destroy both prev and curr + # Are previous and current about to collide? + if ( $_->[$i-1] >= 0 && $_->[$i] < 0 ){ + # If previous has greater absolute value, destroy current only: + if ( $_->[$i-1] > -$_->[$i] ){ + splice @$_, $i, 1; + --$i; # Backtrack 1 because removed current item. + } + # If previous and current have equal absolute value, destroy both: + elsif ( $_->[$i-1] == -$_->[$i] ){ + splice @$_, $i-1, 2; + --$i; --$i; # Backtrack 2 because removed previous and current items. + } + # If current has greater absolute value, destroy previous only: + elsif ( $_->[$i-1] < -$_->[$i] ){ + splice @$_, $i-1, 1; + --$i; --$i; # Backtrack 2 because removed previous item. + } + } + } + + # Announce remnants of original array: + say "Remaining: (@$_)"; +} |
