aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-274/bob-lied/README6
-rw-r--r--challenge-274/bob-lied/blog.txt1
-rw-r--r--challenge-274/bob-lied/perl/ch-1.pl57
-rw-r--r--challenge-274/bob-lied/perl/ch-2.pl91
4 files changed, 152 insertions, 3 deletions
diff --git a/challenge-274/bob-lied/README b/challenge-274/bob-lied/README
index fbef60f528..f308a5c62c 100644
--- a/challenge-274/bob-lied/README
+++ b/challenge-274/bob-lied/README
@@ -1,4 +1,4 @@
-Solutions to weekly challenge 273 by Bob Lied
+Solutions to weekly challenge 274 by Bob Lied
-https://perlweeklychallenge.org/blog/perl-weekly-challenge-273/
-https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-273/bob-lied
+https://perlweeklychallenge.org/blog/perl-weekly-challenge-274/
+https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-274/bob-lied
diff --git a/challenge-274/bob-lied/blog.txt b/challenge-274/bob-lied/blog.txt
new file mode 100644
index 0000000000..b42e7f3cf4
--- /dev/null
+++ b/challenge-274/bob-lied/blog.txt
@@ -0,0 +1 @@
+https://dev.to/boblied/pwc-274-waiting-at-the-bus-stop-1o9g
diff --git a/challenge-274/bob-lied/perl/ch-1.pl b/challenge-274/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..fcf6c36e2e
--- /dev/null
+++ b/challenge-274/bob-lied/perl/ch-1.pl
@@ -0,0 +1,57 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2024, Bob Lied
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge 274 Task 1 Goat Latin
+#=============================================================================
+# You are given a sentence, $sentance.
+# Write a script to convert the given sentence to Goat Latin, a made up
+# language similar to Pig Latin.
+# Rules for Goat Latin:
+# 1) If a word begins with a vowel ("a", "e", "i", "o", "u"),
+# append "ma" to the end of the word.
+# 2) If a word begins with consonant i.e. not a vowel, remove first
+# letter and append it to the end then add "ma".
+# 3) Add letter "a" to the end of first word in the sentence, "aa" to
+# the second word, etc etc.
+#
+# Example 1 Input: $sentence = "I love Perl"
+# Output: "Imaa ovelmaaa erlPmaaaa"
+# Example 2 Input: $sentence = "Perl and Raku are friends"
+# Output: "erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa"
+# Example 3 Input: $sentence = "The Weekly Challenge"
+# Output: "heTmaa eeklyWmaaa hallengeCmaaaa"
+#=============================================================================
+
+use v5.40;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+sub goatLatin($sentence)
+{
+ my $maa = 'ma';
+ join ' ',
+ map { s/^([^aeiou]?)(.*)$/$2$1/ir . ($maa .= 'a') }
+ split /\W+/, $sentence
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( goatLatin("I love Perl"),
+ "Imaa ovelmaaa erlPmaaaa", "Example 1");
+ is( goatLatin("Perl and Raku are friends"),
+ "erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa",
+ "Example 2");
+ is( goatLatin("The Weekly Challenge"),
+ "heTmaa eeklyWmaaa hallengeCmaaaa", "Example 3");
+
+ done_testing;
+}
diff --git a/challenge-274/bob-lied/perl/ch-2.pl b/challenge-274/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..2960ee7591
--- /dev/null
+++ b/challenge-274/bob-lied/perl/ch-2.pl
@@ -0,0 +1,91 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2024, Bob Lied
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge 274 Task 2 Bus Route
+#=============================================================================
+# Several bus routes start from a bus stop near my home, and go to the same
+# stop in town. They each run to a set timetable, but they take different
+# times to get into town.
+#
+# Write a script to find the times - if any - I should let one bus leave and
+# catch a strictly later one in order to get into town strictly sooner.
+#
+# An input timetable consists of the service interval, the offset within the
+# hour, and the duration of the trip.
+# Example 1 Input: [ [12, 11, 41], [15, 5, 35] ]
+# Output: [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]
+# Route 1 leaves every 12 minutes, starting at 11 minutes past the
+# hour (so 11, 23, ...) and takes 41 minutes. Route 2 leaves every
+# 15 minutes, starting at 5 minutes past (5, 20, ...) and takes
+# 35 minutes. At 45 minutes past the hour I could take the route 1
+# bus at 47 past the hour, arriving at 28 minutes past the following
+# hour, but if I wait for the route 2 bus at 50 past I will get to
+# town sooner, at 25 minutes past the next hour.
+#
+# Example 2 Input: [ [12, 3, 41], [15, 9, 35], [30, 5, 25] ]
+# Output: [ 0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59 ]
+#=============================================================================
+
+use v5.40;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+# Calculate the next time that $route stops at or after $minute
+# $route is a triple of [cycle time, first time, time to destination]
+# Returns a pair of [next bus stop time, arrival at destination]
+sub nextBusAt($route, $minute)
+{
+ my ($cycle, $offset, $duration) = $route->@*;
+
+ my $stop = $offset + $cycle * ceil( ($minute - $offset) / $cycle );
+ return [ $stop, $stop + $duration ];
+}
+
+sub busRoute($timetable)
+{
+ use List::Util qw/any/;
+ my @skipToLater;
+ for my $minute ( 0 .. 59 )
+ {
+ # Convert each route to a pair of [stop, arrive] and
+ # sort by next stop time.
+ my @next = sort { $a->[0] <=> $b->[0] }
+ map { nextBusAt($_, $minute) } $timetable->@*;
+
+ my ( $firstStopTime, $firstFinishTime) = (shift @next)->@*;
+
+ push @skipToLater, $minute
+ if any { $_->[1] < $firstFinishTime
+ && $_->[0] != $firstStopTime } @next;
+ }
+
+ return \@skipToLater;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ my $route = [12, 11, 41];
+ is( nextBusAt($route, 0), [11, 52], "StopsAt 0");
+ is( nextBusAt($route, 1), [11, 52], "StopsAt 1");
+ is( nextBusAt($route, 11), [11, 52], "StopsAt 11");
+ is( nextBusAt($route, 12), [23, 64], "StopsAt 12");
+ is( nextBusAt($route, 24), [35, 76], "StopsAt 24");
+ is( nextBusAt($route, 36), [47, 88], "StopsAt 36");
+ is( nextBusAt($route, 48), [59, 100], "StopsAt 48");
+ is( nextBusAt($route, 59), [59, 100], "StopsAt 59");
+
+ is( busRoute( [ [12, 11, 41], [15, 5, 35] ] ), [ 36 .. 47 ] , "Example 1");
+ is( busRoute( [ [12, 3, 41], [15, 9, 35], [30, 5, 25] ] ),
+ [0..3, 25..27, 40..51, 55..59 ] , "Example 2");
+
+ done_testing;
+}