diff options
| author | 冯昶 <fengchang@novel-supertv.com> | 2023-07-24 17:16:48 +0800 |
|---|---|---|
| committer | 冯昶 <fengchang@novel-supertv.com> | 2023-07-24 17:16:48 +0800 |
| commit | 4fda4a4a398e64921020704733556a2ec6dae78a (patch) | |
| tree | f2b70bccff1e2d183104042921d0726f7a8e5f40 /challenge-219 | |
| parent | a296c2a161ce1fffe7c7c1108346c81f027af419 (diff) | |
| parent | e4bdf5dcb6e741f1fb8e1b145fd2111f05ed6445 (diff) | |
| download | perlweeklychallenge-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/README | 6 | ||||
| -rw-r--r-- | challenge-219/bob-lied/perl/ch-1.pl | 39 | ||||
| -rw-r--r-- | challenge-219/bob-lied/perl/ch-2.pl | 130 |
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; +} |
