diff options
| author | Abigail <abigail@abigail.be> | 2021-11-03 17:41:34 +0100 |
|---|---|---|
| committer | Abigail <abigail@abigail.be> | 2021-11-03 17:41:34 +0100 |
| commit | 172d3d442f2e84abb4a29454124d00d50cdae72a (patch) | |
| tree | 3dc6b1687d379f28f76677b262220d93b1b38af4 | |
| parent | 1b32e48dbd84df6f39012c6c90e2b809df190e3b (diff) | |
| download | perlweeklychallenge-club-172d3d442f2e84abb4a29454124d00d50cdae72a.tar.gz perlweeklychallenge-club-172d3d442f2e84abb4a29454124d00d50cdae72a.tar.bz2 perlweeklychallenge-club-172d3d442f2e84abb4a29454124d00d50cdae72a.zip | |
Alternative Perl solution for week 137, part 1
| -rw-r--r-- | challenge-137/abigail/README.md | 4 | ||||
| -rw-r--r-- | challenge-137/abigail/perl/ch-1.pl | 7 | ||||
| -rw-r--r-- | challenge-137/abigail/perl/ch-1a.pl | 68 |
3 files changed, 75 insertions, 4 deletions
diff --git a/challenge-137/abigail/README.md b/challenge-137/abigail/README.md index 0707d1fbd5..49fca86bcd 100644 --- a/challenge-137/abigail/README.md +++ b/challenge-137/abigail/README.md @@ -11,7 +11,9 @@ * [Lua](lua/ch-1.lua) * [Node.js](node/ch-1.js) * [Pascal](pascal/ch-1.p) -* [Perl](perl/ch-1.pl) +* Perl + * [Using loop-up](perl/ch-1.pl) + * [Using Doomsday values](perl/ch-1a.pl) * [Python](python/ch-1.py) * [R](r/ch-1.r) * [Ruby](ruby/ch-1.rb) diff --git a/challenge-137/abigail/perl/ch-1.pl b/challenge-137/abigail/perl/ch-1.pl index 875aca99a4..72e0efe0b4 100644 --- a/challenge-137/abigail/perl/ch-1.pl +++ b/challenge-137/abigail/perl/ch-1.pl @@ -36,15 +36,16 @@ use experimental 'lexical_subs'; # # Now, we could calculate the day of the week of Jan 1 and Dec 31, # either using a module or some handrolled calculations, checking -# whether at least of those days is a Thursday. +# whether at least of those days is a Thursday. # # Or we could just list the 71 years in a 400 year period, and so # some trivial arithmetic. # -# Guess which method we're using. +# We opt to use the latter method in this solution. +# For the former method, see ch-1a.pl. # -my @start_years = qw [1600 2000] +my @start_years = qw [1600 2000]; my @long_year_offsets = qw [ 004 009 015 020 026 032 037 043 048 054 diff --git a/challenge-137/abigail/perl/ch-1a.pl b/challenge-137/abigail/perl/ch-1a.pl new file mode 100644 index 0000000000..32d5f82a0b --- /dev/null +++ b/challenge-137/abigail/perl/ch-1a.pl @@ -0,0 +1,68 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# See ../README.md +# + +# +# Run as: perl ch-1a.pl +# + +# +# A year is a long year if the last day of the year is a Thursday, +# or if the last day of the year is a Friday, and the year is a +# leap year. +# +# To determine the day of the week of Dec 31, we first calculate the +# Doomsday value of the year: this is the day of the week of 4/4, +# 6/6, 8/8, 10/10, 12/12, 5/9, 9/5, 7/11, 11/7, Pi day, the last +# day of February, and January 3 (non leap years) or January 4 (leap years) +# +# Given the day of the week of Dec 12, it's trivial to calculate the +# day of the week of Dec 31. +# +# See also ch-1.pl for an alternative method to solve this. +# + +my $SUNDAY = 0; +my $MONDAY = 1; +my $TUESDAY = 2; +my $WEDNESDAY = 3; +my $THURSDAY = 4; +my $FRIDAY = 5; +my $SATURDAY = 6; + +# +# Given a year, return its "Doomsday" value. +# 0 -> Sunday, 6 -> Saturday +# +sub doomsday ($year) { + use integer; + my $anchor = ($TUESDAY, $SUNDAY, $FRIDAY, $WEDNESDAY) [($year / 100) % 4]; + my $y = $year % 100; + my $doomsday = ((($y / 12) + ($y % 12) + (($y % 12) / 4)) + $anchor) % 7; + $doomsday; +} + +sub is_leap ($year) { + ($year % 400 == 0) || ($year % 4 == 0) && ($year % 100 != 0) +} + +foreach my $year (1900 .. 2100) { + # + # Get the Doomsday value; this is the day of the week of December 12. + # Add 31, subtract 12 to get the day of the week of Dec 31. + # + my $doomsday = doomsday ($year); + my $dec_31 = ($doomsday - 12 + 31) % 7; + say $year if $dec_31 == $THURSDAY || $dec_31 == $FRIDAY && is_leap $year; +} |
