diff options
| -rwxr-xr-x | challenge-212/mattneleigh/perl/ch-1.pl | 106 | ||||
| -rwxr-xr-x | challenge-212/mattneleigh/perl/ch-2.pl | 155 |
2 files changed, 261 insertions, 0 deletions
diff --git a/challenge-212/mattneleigh/perl/ch-1.pl b/challenge-212/mattneleigh/perl/ch-1.pl new file mode 100755 index 0000000000..07d5955463 --- /dev/null +++ b/challenge-212/mattneleigh/perl/ch-1.pl @@ -0,0 +1,106 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +################################################################################ +# Begin main execution +################################################################################ + +my @words = ( + # Given cases + [ + "Perl", + [ 2, 22, 19, 9 ] + ], + [ + "Raku", + [ 24, 4, 7, 17 ] + ], + + # Additional test cases + [ + "AMTK", + [ 0, 7, 25, 21 ] + ], + [ + "IBM", + [ -1, -1, -1 ] + ], + [ + "Wow!", + [ 11, -10, 2, 13 ] + ] +); + +print("\n"); +foreach my $word (@words){ + printf( + "Input: \$word = \'%s\' and \@jump = (%s)\nOutput: %s\n\n", + $word->[0], + join(", ", @{$word->[1]}), + character_rotate($word->[0], @{$word->[1]}) + ); + +} + +exit(0); +################################################################################ +# End main execution; subroutines follow +################################################################################ + + + +################################################################################ +# Rotate the letters of a string a specified number of places within the +# alphabet, wrapping around at the ends as appropriate. Case is preserved; +# non-letter characters are passed through unchanged. Shift values may be +# positive (e.g. 1 shifts A to B) or negative (e.g. -1 shifts B to A). +# Takes two arguments: +# * The string to modify +# * A list of integers that determine how far a character is to be rotated +# within the alphabet; this must be at least as long as the number of +# characters in the string +# Returns: +# * The modified string +################################################################################ +sub character_rotate{ + + my $outstr = ""; + + # Loop over each character of the supplied + # string + foreach my $char (split('', shift())){ + my $base; + + if((ord($char) >= 97) && (ord($char) <= 122)){ + # a-z + $base = 97; + } elsif((ord($char) >= 65) && (ord($char) <= 90)){ + # A-Z + $base = 65; + } else{ + # Something else...? Add it to the output + # string, ignore the jump value for this + # glyph, and skip ahead to the next + # character + $outstr .= $char; + shift(); + next; + } + + # Calculate the new character after the + # rotation value is applied (modular + # division wraps large values back to the + # start of the alphabet) and add it to + # the output string + $outstr .= chr((ord($char) - $base + shift()) % 26 + $base); + } + + return($outstr); + +} + + + diff --git a/challenge-212/mattneleigh/perl/ch-2.pl b/challenge-212/mattneleigh/perl/ch-2.pl new file mode 100755 index 0000000000..47e6d0392b --- /dev/null +++ b/challenge-212/mattneleigh/perl/ch-2.pl @@ -0,0 +1,155 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +################################################################################ +# Begin main execution +################################################################################ + +my @lists = ( + # Given cases + [ + 3, + [ 1, 2, 3, 5, 1, 2, 7, 6, 3 ] + ], + [ + 2, + [ 1, 2, 3 ] + ], + [ + 3, + [ 1, 2, 4, 3, 5, 3 ] + ], + [ + 3, + [ 1, 5, 2, 6, 4, 7 ] + ], + + # Additional test cases + [ + 3, + [ 1, 5, 2, 9, 4, 7 ] + ], +); + +print("\n"); +foreach my $list (@lists){ + my $result = even_split($list->[0], @{$list->[1]}); + + printf( + "Input: \@list = (%s) and \$size = %d\nOutput: %s\n\n", + join(", ", @{$list->[1]}), + $list->[0], + defined($result) ? + "[ " . list_of_lists_to_string(@{$result}) . " ]" + : + "-1" + ); +} + +exit(0); +################################################################################ +# End main execution; subroutines follow +################################################################################ + + + +################################################################################ +# Split a list of integers into a number of sub-lists each containing the +# specified number of members; these sub-lists will also consist of members +# that are numerically sequential (that is to say, each is one greater than the +# number that preceded it) +# Takes two arguments: +# * The number of members to place in each sub-list (e.g. 3 ) +# * The list of integers to examine (e.g. (1, 2, 4, 3, 5, 3) ) +# Returns on success: +# * A ref to a list of sub-lists as described above (e.g. +# [ [ 1, 2, 3 ], [ 3, 4, 5 ] ] ) +# Returns on error: +# * undef if a set of sub-lists as described above cannot be constructed from +# the supplied data and parameter +################################################################################ +sub even_split{ + my $n = int(shift()); + + my $buckets; + + # Can we make equal groups? Quantity of + # integers must divide evenly by $n + return(undef) + if(scalar(@ARG) % $n); + + # Sort the numbers and prepare the right + # quantity of buckets + @ARG = sort(@ARG); + $buckets = [ map([], 1 .. (scalar(@ARG) / $n)) ]; + + # Loop while unplaced numbers remain + while(@ARG){ + my $placed = 0; + + # Loop over each bucket + for my $i (0 .. $#$buckets){ + # Skip this bucket if it's already full + next + if(scalar(@{$buckets->[$i]}) == $n); + + # See if this bucket is empty or this + # number is one greater than the last + # one added to the bucket + if( + (!scalar(@{$buckets->[$i]})) + || + ($ARG[0] == ($buckets->[$i][$#{$buckets->[$i]}] + 1)) + ){ + # Transfer this number to the bucket and + # skip ahead to the next number + push(@{$buckets->[$i]}, shift(@ARG)); + $placed = 1; + last; + } + } + + # Indicate an error if we couldn't place + # this number + return(undef) + unless($placed); + } + + return($buckets); + +} + + + +################################################################################ +# Build a string out of a list of lists. The data will be presented as the +# code that would produce an array ref of values containing the equivalent +# data. +# Takes one argument: +# * The list of lists to stringify (e.g. ( [ 1, 2 ], [ 3, 4 ] ) ) +# Returns +# * A string containing a text representation of contents of the list of lists +# (e.g. "[ 1, 2 ], [ 3, 4 ]" ) +################################################################################ +sub list_of_lists_to_string{ + + return( + join( + ", ", + map( + sprintf( + "[ %s ]", + join(", ", @{$_}) + ), + @ARG + ) + ) + ); + +} + + + |
