aboutsummaryrefslogtreecommitdiff
path: root/challenge-219
diff options
context:
space:
mode:
author冯昶 <fengchang@novel-supertv.com>2023-07-24 17:16:48 +0800
committer冯昶 <fengchang@novel-supertv.com>2023-07-24 17:16:48 +0800
commit4fda4a4a398e64921020704733556a2ec6dae78a (patch)
treef2b70bccff1e2d183104042921d0726f7a8e5f40 /challenge-219
parenta296c2a161ce1fffe7c7c1108346c81f027af419 (diff)
parente4bdf5dcb6e741f1fb8e1b145fd2111f05ed6445 (diff)
downloadperlweeklychallenge-club-4fda4a4a398e64921020704733556a2ec6dae78a.tar.gz
perlweeklychallenge-club-4fda4a4a398e64921020704733556a2ec6dae78a.tar.bz2
perlweeklychallenge-club-4fda4a4a398e64921020704733556a2ec6dae78a.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'challenge-219')
-rw-r--r--challenge-219/bob-lied/README6
-rw-r--r--challenge-219/bob-lied/perl/ch-1.pl39
-rw-r--r--challenge-219/bob-lied/perl/ch-2.pl130
3 files changed, 172 insertions, 3 deletions
diff --git a/challenge-219/bob-lied/README b/challenge-219/bob-lied/README
index 3900c8b0ad..a5ad186116 100644
--- a/challenge-219/bob-lied/README
+++ b/challenge-219/bob-lied/README
@@ -1,4 +1,4 @@
-Solutions to weekly challenge 217 by Bob Lied
+Solutions to weekly challenge 219 by Bob Lied
-https://perlweeklychallenge.org/blog/perl-weekly-challenge-217/
-https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-217/bob-lied
+https://perlweeklychallenge.org/blog/perl-weekly-challenge-219/
+https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-219/bob-lied
diff --git a/challenge-219/bob-lied/perl/ch-1.pl b/challenge-219/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..1383abdad7
--- /dev/null
+++ b/challenge-219/bob-lied/perl/ch-1.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge Task 1 Sorted Squares
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# You are given a list of numbers.
+# Write a script to square each number in the list and return the sorted
+# list, increasing order.
+# Example 1 Input: @list = (-2, -1, 0, 3, 4) Output: (0, 1, 4, 9, 16)
+# Example 2 Input: @list = (5, -4, -1, 3, 6) Output: (1, 9, 16, 25, 36)
+#=============================================================================
+
+use v5.36;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+say "(", join(", ", sortedSquares(@ARGV)->@*), ")";
+
+sub sortedSquares(@numList)
+{
+ [ sort { $a <=> $b } map { $_*$_ } @numList ];
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( sortedSquares(-2,-1,0,3,4), [0,1,4,9,16], "Exmple 1");
+ is( sortedSquares(5,-4,-1,3,6), [1,9,16,25,36], "Exmple 1");
+
+ done_testing;
+}
diff --git a/challenge-219/bob-lied/perl/ch-2.pl b/challenge-219/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..3aec5f604e
--- /dev/null
+++ b/challenge-219/bob-lied/perl/ch-2.pl
@@ -0,0 +1,130 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge Task 2 Travel Expenditure
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# You are given two list, @costs and @days.
+# The list @costs contains the cost of three different types of travel cards
+# you can buy. For example @costs = (5, 30, 90)
+#
+# Index 0 element represent the cost of 1 day travel card.
+# Index 1 element represent the cost of 7 days travel card.
+# Index 2 element represent the cost of 30 days travel card.
+#
+# The list @days contains the day number you want to travel in the year.
+# For example: @days = (1, 3, 4, 5, 6)
+#
+# The above example means you want to travel on day 1, day 3, day 4, day 5
+# and day 6 of the year.
+#
+# Write a script to find the minimum travel cost.
+#
+# Example 1: Input: @costs = (2, 7, 25)
+# @days = (1, 5, 6, 7, 9, 15)
+# Output: 11
+# On day 1, we buy a one day pass for 2 which would cover the day 1.
+# On day 5, we buy seven days pass for 7 which would cover days 5 - 9.
+# On day 15, we buy a one day pass for 2 which would cover the day 15.
+# So the total cost is 2 + 7 + 2 => 11.
+#
+# Example 2: Input: @costs = (2, 7, 25)
+# @days = (1, 2, 3, 5, 7, 10, 11, 12, 14, 20, 30, 31)
+# Output: 20
+# On day 1, we buy a seven days pass for 7 which would cover days 1 - 7.
+# On day 10, we buy a seven days pass for 7 which would cover days 10 - 14.
+# On day 20, we buy a one day pass for 2 which would cover day 20.
+# On day 30, we buy a one day pass for 2 which would cover day 30.
+# On day 31, we buy a one day pass for 2 which would cover day 31.
+# So the total cost is 7 + 7 + 2 + 2 + 2 => 20.
+#=============================================================================
+
+use v5.36;
+
+use List::Util qw/min max/;
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+use constant { _1_DAY_PASS => 0, _7_DAY_PASS => 1, _30_DAY_PASS => 2 };
+
+my $MinCost;
+
+sub _travel($pass, $days, $costSoFar, $passesUsed, $indent)
+{
+ return if @$days == 0;
+ return if $costSoFar >= $MinCost;
+
+
+ for my $passLength ( keys %{$pass} )
+ {
+ my $remainingDays = [ grep { $_ >= $days->[0] + $passLength } @$days ];
+
+ say "${indent}TRY pass=$passLength sofar=$costSoFar days=[$days->@*] --> [$remainingDays->@*]" if $Verbose;
+
+ if ( scalar(@$remainingDays) == 0 )
+ {
+ # Total coverage achieved.
+ my $total = $costSoFar + $pass->{$passLength};
+ print "${indent}FINISH cost=$total " if $Verbose;
+ if ( $total < $MinCost )
+ {
+ $MinCost = $total;
+ say "${indent}BETTER Min=$MinCost seq=[@$passesUsed $passLength]" if $Verbose;
+ }
+ }
+ else
+ {
+ _travel($pass, $remainingDays, $costSoFar + $pass->{$passLength}, [ $passesUsed->@*, $passLength ], "| $indent");
+ }
+ }
+}
+
+sub travel
+{
+ my %args = @_;
+ my $days = [ sort { $a <=> $b } $args{days}->@* ];
+
+ my %pass = ( 1 => $args{costs}->[ _1_DAY_PASS],
+ 7 => $args{costs}->[ _7_DAY_PASS],
+ 30 => $args{costs}->[_30_DAY_PASS] );
+
+ # Start by assuming maximum possible cost.
+ $MinCost = max( values %pass ) * scalar(@$days);
+
+ _travel( \%pass, $days, 0, [], "");
+
+ return $MinCost;
+}
+
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( travel( costs => [2, 7, 25],
+ days => [1, 5, 6, 7, 9, 15] ),
+ 11, "Example 1");
+ is( travel( costs => [2, 7, 25],
+ days => [1, 2, 3, 5, 7, 10, 11, 12, 13, 14, 20, 30, 31] ),
+ 20, "Example 2");
+
+ is( travel( costs => [2, 7, 25],
+ days => [1 .. 30] ),
+ 25, "One month" );
+
+ is( travel( costs => [2, 7, 25],
+ days => [1 .. 30, 101 .. 130] ),
+ 50, "Two months" );
+
+ is( travel( costs => [2, 7, 25],
+ days => [1 .. 30, 101 .. 130, 200] ),
+ 52, "Two months and a day" );
+
+ done_testing;
+}