From 20b474aadf8f8fcb02d5c38f938e3f72ee19087e Mon Sep 17 00:00:00 2001 From: Bob Lied Date: Thu, 20 Jun 2024 19:29:06 -0500 Subject: Week 274 solutions and blog reference --- challenge-274/bob-lied/README | 6 +-- challenge-274/bob-lied/blog.txt | 1 + challenge-274/bob-lied/perl/ch-1.pl | 57 +++++++++++++++++++++++ challenge-274/bob-lied/perl/ch-2.pl | 91 +++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 challenge-274/bob-lied/blog.txt create mode 100644 challenge-274/bob-lied/perl/ch-1.pl create mode 100644 challenge-274/bob-lied/perl/ch-2.pl 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; +} -- cgit