aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2023-04-03 00:40:08 +0100
committerGitHub <noreply@github.com>2023-04-03 00:40:08 +0100
commit7fd0d9c2ba3ec36018ddeb84377e2deda1c36d56 (patch)
tree82c53a2e89c405701854375884d7bfbb73dde676
parent7783ecfe21fbc9bfa8e20c218b03c1266fec3c5a (diff)
parent919379dab5635275f741a6099b18dec457ecb9ac (diff)
downloadperlweeklychallenge-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.txt1
-rwxr-xr-xchallenge-210/robbie-hatley/perl/ch-1.pl102
-rwxr-xr-xchallenge-210/robbie-hatley/perl/ch-2.pl121
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: (@$_)";
+}