aboutsummaryrefslogtreecommitdiff
path: root/challenge-219
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-06-04 22:11:25 +0100
committerGitHub <noreply@github.com>2023-06-04 22:11:25 +0100
commit5306279bd1d9f1b3030943c036fa2a557dc17cb0 (patch)
tree8fcd4d50c29fb2db9f8402da6c3be74a43cdcd8d /challenge-219
parent0849eeff80c7766698bbdd233886b11f2dab2646 (diff)
parent96fbd7d14ecb1cb3a3e923fe0ae9007491aad34b (diff)
downloadperlweeklychallenge-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.txt1
-rwxr-xr-xchallenge-219/steve-g-lynn/perl/ch-1.pdl7
-rwxr-xr-xchallenge-219/steve-g-lynn/perl/ch-2.pl93
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