aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2024-06-23 16:59:51 +0100
committerGitHub <noreply@github.com>2024-06-23 16:59:51 +0100
commitb4970fd33f91f41c173b4705a35e673c4aaacab5 (patch)
tree999e81cd264d8f063259370982b1e8ca200e1c14
parent6cfc29a9990d7e73fdbae6091bb05084556f2712 (diff)
parent2347585f012e261a0c2116a356290d8737760de0 (diff)
downloadperlweeklychallenge-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-xchallenge-274/mattneleigh/perl/ch-1.pl76
-rwxr-xr-xchallenge-274/mattneleigh/perl/ch-2.pl211
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);
+
+}
+
+
+