From d69c546a4fda62fcd899662f52a45e3ba03365c3 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Fri, 29 Jul 2022 15:36:50 +0100 Subject: updated formulae --- challenge-175/james-smith/README.md | 9 ++++++--- challenge-175/james-smith/perl/ch-1.pl | 24 +++++++++++++++++++----- challenge-175/james-smith/perl/ch-2.pl | 7 +++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/challenge-175/james-smith/README.md b/challenge-175/james-smith/README.md index b1aad3d2c1..89f94bc409 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; + ## 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 += 35 - $L[$_-1]) > $L[$_] ) && ($last-=7); sprintf '%04d-%02d-%02d', $yr, $_, $last - } 1..12; + } 1..12 } ``` ### Notes diff --git a/challenge-175/james-smith/perl/ch-1.pl b/challenge-175/james-smith/perl/ch-1.pl index 369e3ced03..3355c93461 100644 --- a/challenge-175/james-smith/perl/ch-1.pl +++ b/challenge-175/james-smith/perl/ch-1.pl @@ -13,19 +13,33 @@ 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); sprintf '%04d-%02d-%02d', $yr, $_, $last - } 1..12; + } 1..12 +} + +#123456789#123456789#123456789#123456789#123456789#123456789#123456789#123456789 +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+=35-$L[$_-1])>$L[$_])&&($l-=7);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 { -- cgit From 066ad6ac3eea1f0d02b5098ca921addade4b784f Mon Sep 17 00:00:00 2001 From: drbaggy Date: Sat, 30 Jul 2022 01:25:34 +0100 Subject: tweaks and shortenings --- challenge-175/james-smith/README.md | 6 ++++-- challenge-175/james-smith/perl/ch-1.pl | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/challenge-175/james-smith/README.md b/challenge-175/james-smith/README.md index 89f94bc409..56bf461373 100644 --- a/challenge-175/james-smith/README.md +++ b/challenge-175/james-smith/README.md @@ -31,7 +31,7 @@ sub last_day_of_months { ## 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 += 35 - $L[$_-1]) > $L[$_] ) && ($last-=7); + map { $last-=7 if $L[$_] < ($last += 35 - $L[$_-1]); sprintf '%04d-%02d-%02d', $yr, $_, $last } 1..12 } @@ -95,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 { @@ -107,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 3355c93461..b4ec450c98 100644 --- a/challenge-175/james-smith/perl/ch-1.pl +++ b/challenge-175/james-smith/perl/ch-1.pl @@ -30,16 +30,18 @@ sub last_day_of_months { ## 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 += 35 - $L[$_-1]) > $L[$_] ) && ($last-=7); + map { $last-=7 if $L[$_] < ($last += 35 - $L[$_-1]); sprintf '%04d-%02d-%02d', $yr, $_, $last } 1..12 } -#123456789#123456789#123456789#123456789#123456789#123456789#123456789#123456789 +# 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+=35-$L[$_-1])>$L[$_])&&($l-=7);sprintf'%04d-%02d-%02d',$y,$_,$l}1..12 + map{$l-=7if$L[$_]<($l+=35-$L[$_-1]); + sprintf'%04d-%02d-%02d',$y,$_,$l}1..12 } -- cgit