diff options
| author | Paulo Custodio <pauloscustodio@gmail.com> | 2021-01-21 21:04:25 +0000 |
|---|---|---|
| committer | Paulo Custodio <pauloscustodio@gmail.com> | 2021-01-21 21:04:25 +0000 |
| commit | 4e01f996153d481dab8d47a79ad8f261666b8ac9 (patch) | |
| tree | 20b339d4df7c2de8ca42b5de4ea375a82a1d01cd | |
| parent | 63c0d699561885257c762e0e04c1a4e6ac3e4212 (diff) | |
| download | perlweeklychallenge-club-4e01f996153d481dab8d47a79ad8f261666b8ac9.tar.gz perlweeklychallenge-club-4e01f996153d481dab8d47a79ad8f261666b8ac9.tar.bz2 perlweeklychallenge-club-4e01f996153d481dab8d47a79ad8f261666b8ac9.zip | |
Remove dependence on Date::Calc
| -rw-r--r-- | challenge-013/paulo-custodio/perl/ch-1.pl | 37 | ||||
| -rw-r--r-- | challenge-019/paulo-custodio/perl/ch-1.pl | 42 |
2 files changed, 63 insertions, 16 deletions
diff --git a/challenge-013/paulo-custodio/perl/ch-1.pl b/challenge-013/paulo-custodio/perl/ch-1.pl index 132cbde073..facf356a55 100644 --- a/challenge-013/paulo-custodio/perl/ch-1.pl +++ b/challenge-013/paulo-custodio/perl/ch-1.pl @@ -22,15 +22,40 @@ use strict; use warnings; use 5.030; -use Date::Calc 'Nth_Weekday_of_Month_Year'; +use constant Friday => 5; -our $Friday = 5; +sub is_leap { + my($year) = @_; + return ((($year % 4)==0 && ($year % 100)!=0) || ($year % 400)==0) ? 1 : 0; +} + +sub days_in_month { + my($year, $month) = @_; + my @dom = (31, 28+is_leap($year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + return $dom[$month-1]; +} + +sub day_of_year { + my($year, $month, $day) = @_; + my $dayno = $day; + $dayno += days_in_month($year, $_) for (1 .. $month-1); + return $dayno; +} + +# return 1..7 <=> Monday..Sunday +sub day_of_week { + my($year, $month, $day) = @_; + my $dayno = day_of_year($year, $month, $day); + my $wdnog = ($dayno + $year + int(($year-1)/4) - int(($year-1)/100) + + int(($year-1)/400) - 2) % 7 + 1; + return $wdnog; +} sub last_friday { - my($year,$month) = @_; - for my $n (reverse 1..5) { - if (my($y,$m,$d) = Nth_Weekday_of_Month_Year($year,$month,$Friday,$n)) { - return ($y,$m,$d); + my($year, $month) = @_; + for my $day (reverse 1 .. days_in_month($year, $month)) { + if (day_of_week($year, $month, $day) == Friday) { + return ($year, $month, $day); } } } diff --git a/challenge-019/paulo-custodio/perl/ch-1.pl b/challenge-019/paulo-custodio/perl/ch-1.pl index 2dd314bf0a..af94bada70 100644 --- a/challenge-019/paulo-custodio/perl/ch-1.pl +++ b/challenge-019/paulo-custodio/perl/ch-1.pl @@ -5,16 +5,41 @@ # Task #1 # Write a script to display months from the year 1900 to 2019 where you find # 5 weekends i.e. 5 Friday, 5 Saturday and 5 Sunday. +# +# Solution: 4 weeks are 28 days, to have 5 week-ends we need additional 3 days (29,30,31), +# therefore 31st must be a Sunday use strict; use warnings; use 5.030; -use Date::Calc qw( Nth_Weekday_of_Month_Year ); -use constant { - Friday => 5, - Saturday => 6, - Sunday => 7 -}; +use constant Sunday => 7; + +sub is_leap { + my($year) = @_; + return ((($year % 4)==0 && ($year % 100)!=0) || ($year % 400)==0) ? 1 : 0; +} + +sub days_in_month { + my($year, $month) = @_; + my @dom = (31, 28+is_leap($year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + return $dom[$month-1]; +} + +sub day_of_year { + my($year, $month, $day) = @_; + my $dayno = $day; + $dayno += days_in_month($year, $_) for (1 .. $month-1); + return $dayno; +} + +# return 1..7 <=> Monday..Sunday +sub day_of_week { + my($year, $month, $day) = @_; + my $dayno = day_of_year($year, $month, $day); + my $wdnog = ($dayno + $year + int(($year-1)/4) - int(($year-1)/100) + + int(($year-1)/400) - 2) % 7 + 1; + return $wdnog; +} for my $year (1900 .. 2019) { for my $month (1 .. 12) { @@ -25,8 +50,5 @@ for my $year (1900 .. 2019) { sub five_weekends { my($year, $month) = @_; - return unless Nth_Weekday_of_Month_Year($year, $month, Friday, 5); - return unless Nth_Weekday_of_Month_Year($year, $month, Saturday, 5); - return unless Nth_Weekday_of_Month_Year($year, $month, Sunday, 5); - return 1; + return days_in_month($year, $month)==31 && day_of_week($year, $month, 31)==Sunday; } |
