aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-175/james-smith/README.md15
-rw-r--r--challenge-175/james-smith/perl/ch-1.pl28
-rw-r--r--challenge-175/james-smith/perl/ch-2.pl7
3 files changed, 35 insertions, 15 deletions
diff --git a/challenge-175/james-smith/README.md b/challenge-175/james-smith/README.md
index b1aad3d2c1..56bf461373 100644
--- a/challenge-175/james-smith/README.md
+++ b/challenge-175/james-smith/README.md
@@ -26,11 +26,14 @@ my @L = (31,31,28,31,30,31,30,31,31,30,31,30,31);
sub last_day_of_months {
my $yr = shift;
- $L[2] = (my $ly = !( $yr%400 && ( ($yr%4) || !($yr%100) ) )) ? 29 : 28;
- my $last = 31 - ( int(($yr%100)/4) - $ly + 2 * (int(3 - $yr/100)%4) + $yr%100 ) % 7;
- map { ( ($last += 35 - $L[$_-1]) > $L[$_] ) && ($last-=7);
+ ## Compute if leap year - set the length of feb accordingly.
+ $L[2] = (my $ly = !($yr%400) ^ !($yr%100) ^ !($yr%4) ) ? 29 : 28;
+ ## Compute the last Sunday in december of the previous year
+ my $last = 31 - ( int($yr%100/4) - $ly + 6 - 2*$yr/100%4 + $yr%100 ) % 7;
+ ## Finally work out the last days of the following 2 months.
+ map { $last-=7 if $L[$_] < ($last += 35 - $L[$_-1]);
sprintf '%04d-%02d-%02d', $yr, $_, $last
- } 1..12;
+ } 1..12
}
```
### Notes
@@ -92,7 +95,7 @@ We can rewrite this as a 1-liner using `List::Util`s product function.
Now there is a second nasty trick here - which if you are used to javascript *self-executing closure*. The trick allows us here to
use the result of the totient calculation and use it to calculate the `t(n) + S( t(n) )` calculation without a *temporary* variable.
-The code reduces to, watch out for the two difference `$_[]` and the `$_->[]`...:
+The code reduces to this, watch out for the two difference `$_[]` and the `$_->[]`...:
```perl
sub st {
@@ -104,3 +107,5 @@ sub st {
);
}
```
+
+The longer form is about 10-15% faster - due to the map and use of external method product...
diff --git a/challenge-175/james-smith/perl/ch-1.pl b/challenge-175/james-smith/perl/ch-1.pl
index 369e3ced03..b4ec450c98 100644
--- a/challenge-175/james-smith/perl/ch-1.pl
+++ b/challenge-175/james-smith/perl/ch-1.pl
@@ -13,19 +13,35 @@ my @L = (31,31,28,31,30,31,30,31,31,30,31,30,31);
## calendar ranges from 1582 to 2016. The UK didn't adopt the calendar into 1754,
## where in large parts of Europe is was adopted from 1582.
-foreach my $yr ( @ARGV ) {
- say join ' ', last_day_of_months( $yr );
+say "LONG";
+foreach ( @ARGV ) {
+ say " @{[last_day_of_months($_)]}";
}
+say "COMPACT";
+foreach ( @ARGV ) {
+ say " @{[last_day_of_months($_)]}";
+}
+say '';
sub last_day_of_months {
my $yr = shift;
## Compute if leap year - set the length of feb accordingly.
- $L[2] = (my $ly = !( $yr%400 && ( ($yr%4) || !($yr%100) ) )) ? 29 : 28;
+ $L[2] = (my $ly = !($yr%400) ^ !($yr%100) ^ !($yr%4) ) ? 29 : 28;
## Compute the last Sunday in december of the previous year
- my $last = 31 - ( int(($yr%100)/4) - $ly + 2 * (int(3 - $yr/100)%4) + $yr%100 ) % 7;
+ my $last = 31 - ( int($yr%100/4) - $ly + 6 - 2*$yr/100%4 + $yr%100 ) % 7;
## Finally work out the last days of the following 2 months.
- map { ( ($last += 35 - $L[$_-1]) > $L[$_] ) && ($last-=7);
+ map { $last-=7 if $L[$_] < ($last += 35 - $L[$_-1]);
sprintf '%04d-%02d-%02d', $yr, $_, $last
- } 1..12;
+ } 1..12
+}
+
+# 1 2 3 4 5
+#23456789#123456789#123456789#123456789#123456789#1
+sub l {
+ my$y=pop;
+ $L[2]=(my$f=!($y%400)^!($y%100)^!($y%4))?29:28;
+ my$l=31-(int($y%100/4)-$f+6-2*$y/100%4+$y%100)%7;
+ map{$l-=7if$L[$_]<($l+=35-$L[$_-1]);
+ sprintf'%04d-%02d-%02d',$y,$_,$l}1..12
}
diff --git a/challenge-175/james-smith/perl/ch-2.pl b/challenge-175/james-smith/perl/ch-2.pl
index 946839b86b..10738e46ee 100644
--- a/challenge-175/james-smith/perl/ch-2.pl
+++ b/challenge-175/james-smith/perl/ch-2.pl
@@ -33,10 +33,9 @@ say sprintf 'Expanded - %10.6f %10.6f', $t2-$t1, 100*($t2-$t1)/($t1-$t0);
sub st {
state @T = (0,0);
- $T[ $_[0] ] //= sub{$_[0]+st($_[0])}->(
- product
- map { $_->[0]**($_->[1]-1) * ($_->[0]-1) }
- factor_exp $_[0]);
+ $T[ $_[0] ] //= sub{ $_[0]+st($_[0]) }->(
+ product map { $_->[0]**($_->[1]-1) * ($_->[0]-1) } factor_exp $_[0]
+ );
}
sub sum_totients {