diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2023-06-04 22:11:25 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-04 22:11:25 +0100 |
| commit | 5306279bd1d9f1b3030943c036fa2a557dc17cb0 (patch) | |
| tree | 8fcd4d50c29fb2db9f8402da6c3be74a43cdcd8d /challenge-219 | |
| parent | 0849eeff80c7766698bbdd233886b11f2dab2646 (diff) | |
| parent | 96fbd7d14ecb1cb3a3e923fe0ae9007491aad34b (diff) | |
| download | perlweeklychallenge-club-5306279bd1d9f1b3030943c036fa2a557dc17cb0.tar.gz perlweeklychallenge-club-5306279bd1d9f1b3030943c036fa2a557dc17cb0.tar.bz2 perlweeklychallenge-club-5306279bd1d9f1b3030943c036fa2a557dc17cb0.zip | |
Merge pull request #8171 from steve-g-lynn/branch-for-challenge-219
pwc 219
Diffstat (limited to 'challenge-219')
| -rw-r--r-- | challenge-219/steve-g-lynn/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-219/steve-g-lynn/perl/ch-1.pdl | 7 | ||||
| -rwxr-xr-x | challenge-219/steve-g-lynn/perl/ch-2.pl | 93 |
3 files changed, 101 insertions, 0 deletions
diff --git a/challenge-219/steve-g-lynn/blog.txt b/challenge-219/steve-g-lynn/blog.txt new file mode 100644 index 0000000000..6df602d517 --- /dev/null +++ b/challenge-219/steve-g-lynn/blog.txt @@ -0,0 +1 @@ +https://thiujiac.blogspot.com/2023/06/pwc-219.html diff --git a/challenge-219/steve-g-lynn/perl/ch-1.pdl b/challenge-219/steve-g-lynn/perl/ch-1.pdl new file mode 100755 index 0000000000..8984fc03fe --- /dev/null +++ b/challenge-219/steve-g-lynn/perl/ch-1.pdl @@ -0,0 +1,7 @@ +#!/usr/bin/pdl + +sub sorted_squares {$list=pdl @_; ($list*$list)->qsort; } + +p &sorted_squares(-2,-1,0,3,4); #-- [0 1 4 9 16] +p &sorted_squares(5,-4,-1,3,6); #-- [1 9 16 25 36] + diff --git a/challenge-219/steve-g-lynn/perl/ch-2.pl b/challenge-219/steve-g-lynn/perl/ch-2.pl new file mode 100755 index 0000000000..e138df34e1 --- /dev/null +++ b/challenge-219/steve-g-lynn/perl/ch-2.pl @@ -0,0 +1,93 @@ +#!/usr/bin/env -S perl -wl + +use PDL; +use PDL::NiceSlice; +use PDL::AutoLoader; + +sub travel_expenditure { + my ($ra_costs, $ra_days)=@_; + my $costs=pdl $ra_costs; + + #-- input validation check that costs are reasonable + #-- 7 day price is less than 7 * daily price + #-- 7 day price is greater than daily price + + (scalar(@$ra_costs) == 3) || (die "bad costs"); + + ( ($ra_costs->[1] < (7*$ra_costs->[0])) + && ($ra_costs->[1] > $ra_costs->[0]) ) + || (die "bad costs"); + + #-- 30 day price is less than 30/7* 7-day price + #-- 30 day price is greater than 7-day price + + ( ($ra_costs->[2] < (30/7*$ra_costs->[1])) + && ($ra_costs->[2] > $ra_costs->[1]) ) + || (die "bad costs"); + + + #-- input validation check that dates are in 0 .. 31 + (((pdl $ra_days)->flat->byte)->max > 31) && (die "bad date"); + (((pdl $ra_days)->flat->byte)->min < 1) && (die "bad date"); + + + #-- store days as a 31-element boolean + #-- with 1 at index corresponding to a travel day + #-- and 0 at the index for non-travel days + my $days=zeros(31); + $days(pdl($ra_days)-1).=1; + + + #-- worth paying for a whole month? + #-- check if # of days is greater than 30-day price / 7-day price * 7 + my $candidates=pdl [Inf, Inf]; #-- candidate solutions + + if ($days->sum > ($ra_costs->[2] / $ra_costs->[1] * 7)) { + if ($days(0) & $days(30)) { + #if both 1st and last day of 31-day month, then .. + $candidates(0) .= $ra_costs->[2]+$ra_costs->[0]; + #cost is 30 days price + 1 day price + } + else { + return $ra_costs->[2]; + } + + } + my $weekly_card=0; + my $days_paid_weekly=0; + my $weekly_cutoff= int( $ra_costs->[1] / $ra_costs->[0] )+1; + + #-- cycle through $days looking for clusters of more than + #-- 7-day price / 1-day price travel days in a 7-day stretch + #-- (weekly cutoff days in a 7-day stretch) + + my $ctr=0; + + MYLOOP: while ($ctr <= (30 - $weekly_cutoff)) { + #-- slow interpreted loop is good enough + #-- because the days vector won't scale beyond 31 days + + #-- start counting 7 days from a travel day only + if ($days($ctr)==0){ + $ctr++; + next MYLOOP; + } + my $days_forward = (pdl (6, 30-$ctr) )->min; + if ($days($ctr:($ctr+$days_forward))->sum >= $weekly_cutoff) { + $weekly_card++; + $days_paid_weekly += $days($ctr:($ctr+$days_forward))->sum; + $ctr += $days_forward+1; + } + else { + $ctr += 1; + } + } + $candidates(1) .= $weekly_card*$costs(1) + +( ($days->sum)-$days_paid_weekly ) * $costs(0); + return $candidates->flat->min; +} + +print &travel_expenditure([3.5,7,25],[1..21,25..31]); #-- 28 +print &travel_expenditure([2,7,25],[2..26,31]); #-- 25 +print &travel_expenditure([2,7,25],[1,5,6,7,9,15]); #-- 11 +print &travel_expenditure([2,7,25],[1..3,5,7,10..12, 14, 20, 30, 31]); #-- 20 |
