aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-239/mattneleigh/perl/ch-1.pl101
-rwxr-xr-xchallenge-239/mattneleigh/perl/ch-2.pl133
2 files changed, 234 insertions, 0 deletions
diff --git a/challenge-239/mattneleigh/perl/ch-1.pl b/challenge-239/mattneleigh/perl/ch-1.pl
new file mode 100755
index 0000000000..9899519266
--- /dev/null
+++ b/challenge-239/mattneleigh/perl/ch-1.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @string_sets = (
+ [
+ [ "ab", "c" ],
+ [ "a", "bc" ]
+ ],
+ [
+ [ "ab", "c" ],
+ [ "ac", "b" ]
+ ],
+ [
+ [ "ab", "cd", "e" ],
+ [ "abcde" ]
+ ]
+);
+
+print("\n");
+foreach my $string_set (@string_sets){
+ printf(
+ "Input: \@arr1 = (%s)\n \@arr2 = (%s)\nOutput: %s\n\n",
+ join(", ", map("\"" . $_ . "\"", @{$string_set->[0]})),
+ join(", ", map("\"" . $_ . "\"", @{$string_set->[1]})),
+ string_arrays_concatenate_uniformly($string_set) ?
+ "true"
+ :
+ "false"
+ );
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Given a ref to an array of arrays of strings (see below) determine whether
+# the strings in each array concatenate to the same word/string
+# Takes one argument:
+# * A ref to an array of arrays of strings, of which there must be at least two
+# (e.g.
+# [
+# [ "ab", "cd", "e" ],
+# [ "abcde" ],
+# [ "abcd", "e" ]
+# ]
+# )
+# Returns on success:
+# * 0 if any array contains strings that do NOT concatenate to the same word as
+# all the others
+# * 1 if all arrays contain strings that concatenate to the same word
+# Returns on error:
+# * undef if there are not at least two arrays of strings
+################################################################################
+sub string_arrays_concatenate_uniformly{
+
+ # Need at least two arrays of strings
+ return(undef)
+ if(scalar(@{$ARG[0]}) < 2);
+
+ my $baseword;
+
+ # Examine each array of strings
+ foreach my $i (0 .. $#{$ARG[0]}){
+ my $word = "";
+
+ # Concatenate each string in this array
+ foreach my $string (@{$ARG[0][$i]}){
+ $word .= $string;
+ }
+
+ if($i){
+ # Not the first word concatenated...
+ # return 0 if the new word doesn't match
+ # the first one
+ return(0)
+ if($word ne $baseword);
+ } else{
+ # This is the first word concatenated-
+ # store it
+ $baseword = $word;
+ }
+ }
+
+ # Everything matched
+ return(1);
+
+}
+
+
+
diff --git a/challenge-239/mattneleigh/perl/ch-2.pl b/challenge-239/mattneleigh/perl/ch-2.pl
new file mode 100755
index 0000000000..52e2888f3b
--- /dev/null
+++ b/challenge-239/mattneleigh/perl/ch-2.pl
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @string_sets = (
+ [
+ [ "ad", "bd", "aaab", "baa", "badab" ],
+ "ab"
+ ],
+ [
+ [ "a", "b", "c", "ab", "ac", "bc", "abc" ],
+ "abc"
+ ],
+ [
+ [ "cc", "acd", "b", "ba", "bac", "bad", "ac", "d" ],
+ "cad"
+ ]
+);
+
+print("\n");
+foreach my $string_set (@string_sets){
+ printf(
+ "Input: \@str = (%s)\n \$allowed = \"%s\"\nOutput: %d\n\n",
+ join(", ", map("\"" . $_ . "\"", @{$string_set->[0]})),
+ $string_set->[1],
+ count_consistent_strings($string_set->[1], @{$string_set->[0]})
+ );
+}
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Count the number of consistent strings within a set of strings- that is to
+# say, the strings that only contain letters from a set of allowed letters;
+# case will be ignored for matching purposes, as will be non-letter (not a-z)
+# characters
+# Takes two arguments:
+# * A string containing "allowed" letters to be looked for in the other strings
+# (e.g. "cad" )
+# * A list of other strings to examine (e.g. ( "cc", "acd", "b", "ba", "bac",
+# "bad", "ac", "d" ) )
+# Returns:
+# * The number of subsequent strings that were consistent- the ones that only
+# contained letters from the first string (e.g. 4 )
+################################################################################
+sub count_consistent_strings{
+ # Make a hash from the allowed characters in
+ # the first string for, easy lookup
+ my %allowed = map(
+ { $_ => 1 }
+ unique_sorted_letters(shift())
+ );
+ my $count = 0;
+
+ # Examine each remaining string
+ foreach my $string (@ARG){
+ my $increment = 1;
+
+ # Compare each letter in the string with the
+ # set of permitted letters
+ foreach my $letter (unique_sorted_letters($string)){
+ unless($allowed{$letter}){
+ # Letter not allowed- clear the increment
+ # flag and stop examining letters
+ $increment = 0;
+ last;
+ }
+ }
+
+ # Increment count if all letters were
+ # allowed
+ $count++
+ if($increment);
+ }
+
+ return($count);
+
+}
+
+
+
+################################################################################
+# Given a string, produce a sorted array of unique letters therefrom; all
+# letters are lower-cased, and all non-letter characters (not a-z) are ignored
+# Takes one argument:
+# * The string to examine (e.g. "Hello there!" )
+# Returns:
+# * A sorted list of the unique characters in the string (e.g. ( "e", "h", "l",
+# "o", "r", "t" ) )
+################################################################################
+sub unique_sorted_letters{
+ # Store the sorted characters from the
+ # arg with, all letters lower-cased
+ my @chars = sort(split("", lc(shift())));
+ my $i = 0;
+
+ # Examine each character within the
+ # (probably shrinking) list
+ while($i <= $#chars){
+ if(
+ # Character is not a letter
+ !($chars[$i] =~ m/[a-z]/)
+ ||
+ # Not the first character and it's a
+ # duplicate of the previous char
+ ($i && ($chars[$i] eq $chars[$i - 1]))
+ ){
+ # Remove it
+ splice(@chars, $i, 1);
+ next;
+ }
+
+ # Move on to the next character
+ $i++;
+ }
+
+ return(@chars);
+
+}
+
+
+