diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2024-06-23 16:59:51 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-23 16:59:51 +0100 |
| commit | b4970fd33f91f41c173b4705a35e673c4aaacab5 (patch) | |
| tree | 999e81cd264d8f063259370982b1e8ca200e1c14 | |
| parent | 6cfc29a9990d7e73fdbae6091bb05084556f2712 (diff) | |
| parent | 2347585f012e261a0c2116a356290d8737760de0 (diff) | |
| download | perlweeklychallenge-club-b4970fd33f91f41c173b4705a35e673c4aaacab5.tar.gz perlweeklychallenge-club-b4970fd33f91f41c173b4705a35e673c4aaacab5.tar.bz2 perlweeklychallenge-club-b4970fd33f91f41c173b4705a35e673c4aaacab5.zip | |
Merge pull request #10292 from mattneleigh/pwc274
new file: challenge-274/mattneleigh/perl/ch-1.pl
| -rwxr-xr-x | challenge-274/mattneleigh/perl/ch-1.pl | 76 | ||||
| -rwxr-xr-x | challenge-274/mattneleigh/perl/ch-2.pl | 211 |
2 files changed, 287 insertions, 0 deletions
diff --git a/challenge-274/mattneleigh/perl/ch-1.pl b/challenge-274/mattneleigh/perl/ch-1.pl new file mode 100755 index 0000000000..d8617e5568 --- /dev/null +++ b/challenge-274/mattneleigh/perl/ch-1.pl @@ -0,0 +1,76 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +################################################################################ +# Begin main execution +################################################################################ + +my @sentences = ( + "I love Perl", + "Perl and Raku are friends", + "The Weekly Challenge" +); + +print("\n"); +foreach my $sentence (@sentences){ + printf( + "Input: \$sentence = \"%s\"\nOutput: \"%s\"\n\n", + $sentence, + to_goat_latin($sentence) + ); +} + +exit(0); +################################################################################ +# End main execution; subroutines follow +################################################################################ + + + +################################################################################ +# Convert a supplied sentence to Goat Latin, by processing each word according +# to the following rules: +# 1) If a word begins with a vowel, append "ma" to the end of the word +# 2) If a word begins with consonant, remove the first letter and append it +# to the end, then append "ma" +# 3) Append letter "a" to the end of first word in the sentence, "aa" to the +# second word, etc etc. +# Takes one argument: +# * A sentence to examine (e.g. "I love Perl") +# Returns: +# * The supplied sentence, converted to Goat Latin (e.g. "Imaa ovelmaaa +# erlPmaaaa") +################################################################################ +sub to_goat_latin{ + + my @words = split(" ", $ARG[0]); + my $suffix = "ma"; + + # Examine each word + foreach my $word (@words){ + if($word !~ m/^[aeiouAEIOU]/){ + # Word begins with a not-vowel- swap + # its first letter to the end (substr() + # removes the character from $word en + # passant before returning it to be + # appended) + $word .= substr($word, 0, 1, ""); + } + + # Add "ma" suffix plus the appropriate + # number of a's, which will increase + # with each word + $word .= ($suffix .= "a"); + } + + # Recombine the words into a sentence + # and return + return(join(" ", @words)); + +} + + + diff --git a/challenge-274/mattneleigh/perl/ch-2.pl b/challenge-274/mattneleigh/perl/ch-2.pl new file mode 100755 index 0000000000..46dc3207a5 --- /dev/null +++ b/challenge-274/mattneleigh/perl/ch-2.pl @@ -0,0 +1,211 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +################################################################################ +# Begin main execution +################################################################################ + +my @timetables = ( + [ + [ 12, 11, 41 ], + [ 15, 5, 35 ] + ], + [ + [ 12, 3, 41 ], + [ 15, 9, 35 ], + [ 30, 5, 25 ] + ] +); + +print("\n"); +foreach my $timetable (@timetables){ + printf( + "Input: [ %s ]\nOutput: [ %s ]\n\n", + join( + ", ", + map( + "[ " . join(", ", @{$_}) . " ]", + @{$timetable} + ) + ), + join(", ", bus_skip_times($timetable)) + ); +} + +exit(0); +################################################################################ +# End main execution; subroutines follow +################################################################################ + + + +################################################################################ +# Given an array of arrays of integers that define a bus timetable in terms of +# headway between runs, the time of the first run of the hour, and the time it +# takes to reach a destination downtown, determine during which minutes of the +# hour a rider should wait and skip the next bus in order to take a later bus +# that arrives sooner +# Takes one argument: +# * A ref to an array of arrays of integers that define a bus timetable (e.g. +# [ +# [ 12, 3, 41 ], # [ Headway, Initial offset, Length of run ] +# [ 15, 9, 35 ], +# [ 30, 5, 25 ] +# ] +# ) +# Returns: +# * A list of minutes within an hour in which a rider should wait and skip the +# next bus in favor of the one after, which will arrive at their destination +# sooner (e.g. ( 0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, +# 49, 50, 51, 55, 56, 57, 58, 59 ) ) +################################################################################ +sub bus_skip_times{ + my $timetable = shift(); + + my $lookahead_limit = $#$timetable; + my %arrival_times; + my @skip_times; + + # Create a table of unique arrival times, + # keyed by departure time + foreach my $route (@{$timetable}){ + my $departure_time = $route->[1]; + + while($departure_time < 60){ + if($arrival_times{$departure_time}){ + # There is an existing arrival time for this + # departure time + if( + $arrival_times{$departure_time} + > + ($departure_time + $route->[2]) + ){ + # This arrival time would be sooner- store it + # instead + $arrival_times{$departure_time} = + $departure_time + $route->[2]; + } + } else{ + # No existing arrival time for this departure + # time + $arrival_times{$departure_time} = + $departure_time + $route->[2]; + } + + # Advance the departure time by the given + # headway + $departure_time += $route->[0]; + } + + # Add an initial departure time for the NEXT + # hour, in case the next bus not to skip + # departs then + $departure_time = $route->[1] + 60; + if($arrival_times{$departure_time}){ + # There is an existing arrival time for this + # departure time + if( + $arrival_times{$departure_time} + > + ($departure_time + $route->[2]) + ){ + # This arrival time would be sooner- store it + # instead + $arrival_times{$departure_time} = + $departure_time + $route->[2]; + } + } else{ + # No existing arrival time for this departure + # time + $arrival_times{$departure_time} = + $departure_time + $route->[2]; + } + + } + + # Briefly store a sorted list of all + # departure times + @skip_times = sort({ $a <=> $b } keys(%arrival_times)); + + # Then replace it with the list of times to + # skip... + @skip_times = map( + { + my $arrival_time = $arrival_times{$skip_times[$_]}; + my $skip = undef; + + # Scan ahead of the current index for more + # optimal arrival times- but only for so many + # departure times as there are routes in the + # timetable + for my $index ( + $_ + 1 + .. + ( + $_ + $lookahead_limit <= $#skip_times ? + $_ + $lookahead_limit + : + $#skip_times + ) + ){ + if( + $arrival_times{$skip_times[$index]} + < + $arrival_time + ){ + # A more optimal arrival time was found; mark + # THIS departure time as skippable and stop + # searching + $skip = $skip_times[$_]; + last; + } + } + + defined($skip) ? + # This departure time is to be skipped... + ( + # ...so make a list of times... + ( + # ...checking to see if this isn't the first + # departure time... + $_ ? + # ...if it's not, start just after the + # previous departure time... + ($skip_times[$_ - 1] + 1) + : + # ...if it is, start from zero... + 0 + ) + .. + # ...and continue to the current time to be + # skipped + $skip + ) + : + # This departure time is NOT to be skipped... + # return an empty list + (); + } + + # Get a list of indices within the list of + # departure times, excluding the last one + 0 .. $#skip_times - 1 + ); + + # Remove any trailing times that are past the + # end of the hour (as happens if an initial + # departure time, occuring in the next hour, + # is to be skipped) + while($skip_times[-1] > 59){ + pop(@skip_times); + } + + return(@skip_times); + +} + + + |
