aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-342/mattneleigh/perl/ch-1.pl96
-rwxr-xr-xchallenge-342/mattneleigh/perl/ch-2.pl79
2 files changed, 175 insertions, 0 deletions
diff --git a/challenge-342/mattneleigh/perl/ch-1.pl b/challenge-342/mattneleigh/perl/ch-1.pl
new file mode 100755
index 0000000000..7bdffaab02
--- /dev/null
+++ b/challenge-342/mattneleigh/perl/ch-1.pl
@@ -0,0 +1,96 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @strings = (
+ "a0b1c2",
+ "abc12",
+ "0a2b1c3",
+ "1a23",
+ "ab123"
+);
+
+print("\n");
+foreach my $string (@strings){
+ printf(
+ "Input: \$str = \"%s\"\nOutput: \"%s\"\n\n",
+ $string,
+ reorder_string($string)
+ );
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Given a string consisting only of digits and letters, reorder the characters
+# therein so that there are not two adjacent numbers or letters, and the
+# resulting string has the smallest lexicographical value possible given the
+# available characters
+# Takes one argument:
+# * The string to examine (e.g. "0a2b1c3")
+# Returns:
+# * A string containing all the letters and numbers from the provided string,
+# reordered as specified above (e.g. "0a1b2c3")
+# -- OR --
+# * An empty string if the provided string cannot be reordered as specified
+################################################################################
+sub reorder_string{
+ # Split the incoming string into characters and
+ # sort them; numbers will be at the start of
+ # the list
+ my @letters = sort(split("", shift()));
+
+ my @numbers;
+ my $longer;
+ my $shorter;
+ my $reformatted;
+
+ # Separate numbers from letters
+ while($letters[0] =~ m/\d/){
+ push(@numbers, shift(@letters));
+ }
+
+ # If the difference in the number of numbers
+ # and letters won't permit them to be merged
+ # without adjacent instances of either, return
+ # an empty string
+ return("")
+ if(abs(scalar(@numbers) - scalar(@letters)) > 1);
+
+ # Determine which list is the longer of the two;
+ # if they are equal, assign numbers as the
+ # "longer" one by default as they have a lower
+ # lexicographical sorting value
+ if(scalar(@letters) > scalar(@numbers)){
+ $longer = \@letters;
+ $shorter = \@numbers;
+ } else{
+ $longer = \@numbers;
+ $shorter = \@letters;
+ }
+
+ # Merge the two character lists, longest first
+ while(@{$shorter}){
+ $reformatted .= shift(@{$longer});
+ $reformatted .= shift(@{$shorter});
+ }
+ $reformatted .= shift(@{$longer})
+ if(@{$longer});
+
+ return($reformatted);
+
+}
+
+
+
diff --git a/challenge-342/mattneleigh/perl/ch-2.pl b/challenge-342/mattneleigh/perl/ch-2.pl
new file mode 100755
index 0000000000..e542b06d55
--- /dev/null
+++ b/challenge-342/mattneleigh/perl/ch-2.pl
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @strings = (
+ "0011",
+ "0000",
+ "1111",
+ "0101",
+ "011101"
+);
+
+print("\n");
+foreach my $string (@strings){
+ printf(
+ "Input: \$str = \"%s\"\nOutput: %d\n\n",
+ $string,
+ calculate_max_score($string)
+ );
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Given a string consisting only of ones and zeros, calculate the maximum score
+# that can be achieved by splitting the string into two portions of non-zero
+# length, where the zeros (0) in the left portion and the ones (1) in the right
+# portion are each worth one point
+# Takes one argument:
+# * The string to examine (e.g. "011101")
+# Returns:
+# * The maximum score calculated as descibed above (e.g. 5)
+################################################################################
+sub calculate_max_score{
+ my $string = shift();
+
+ my $max_position = length($string) - 1;
+ my $left_score = 0;
+ my $right_score = 0;
+ my $max_score = 0;
+
+ # Count the ones on the right side (which is
+ # the whole string at this point)
+ for my $i (0 .. $rightmost_pos){
+ $right_score++
+ if(substr($string, $i, 1));
+ }
+
+ # Scan the string from left to right, updating
+ # the positional scores as appropriate; if a
+ # new maximum score is seen, it will be stored
+ $rightmost_pos--;
+ for my $i (0 .. $rightmost_pos){
+ if(substr($string, $i, 1)){
+ $right_score--;
+ } else{
+ $left_score++
+ }
+ $max_score = $left_score + $right_score
+ if(($left_score + $right_score) > $max_score);
+ }
+
+ return($max_score);
+
+}
+
+
+