diff options
Diffstat (limited to 'challenge-132/abigail/perl/ch-1.pl')
| -rw-r--r-- | challenge-132/abigail/perl/ch-1.pl | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/challenge-132/abigail/perl/ch-1.pl b/challenge-132/abigail/perl/ch-1.pl new file mode 100644 index 0000000000..1500742a2c --- /dev/null +++ b/challenge-132/abigail/perl/ch-1.pl @@ -0,0 +1,81 @@ +#!/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-1.pl < input-file +# + +# +# First question we need to ask for any date related exercise is +# "What calendar are we using?". If you answer "Gregorian", then +# the next question is, "Where are we using the calendar?", as +# different countries switched to the Gregorian calendar at different +# times. The first countries switched in the 16th century, but others +# switched as late as the 20th century. +# + +# +# We will opt to use the proleptic Gregorian calendar, which is basically +# the Gregorian calendar extended backwards to the time no Gregorian +# calender existed. +# +# Since the format is given as YYYY/MM/DD, we will assume non-negative years. +# + +# +# We could pull one of the gazillion date modules from CPAN and let it +# do the calculations. But we'll do the calculations ourselves. We'll +# take the date, calculate its Julian Day number (rounded down, as we don't +# care about hours and minutes), compare it to the Julian Day number of today, +# and then calculate the Julian Day numbers of the target dates, after +# which we convert them back to dates. +# + +# +# Conversion functions from Wikipedia +# + +sub g2j ($Y, $M, $D) { + use integer; + (1461 * ($Y + 4800 + ($M - 14) / 12)) / 4 + + (367 * ($M - 2 - 12 * (($M - 14) / 12))) / 12 - + (3 * (($Y + 4900 + ($M - 14) / 12) / 100)) / 4 + $D - 32075 +} + +sub j2g ($J) { + use integer; + my $e = 4 * ($J + 1401 + (((4 * $J + 274277) / 146097) * 3) / 4 - 38) + 3; + my $D = ((5 * (($e % 1461) / 4) + 2) % 153) / 5 + 1; + my $M = (((5 * (($e % 1461) / 4) + 2) / 153 + 2) % 12) + 1; + my $Y = ($e / 1461) - 4716 + (12 + 2 - $M) / 12; + ($Y, $M, $D) +} + + +my @TODAY = (2021, 9, 22); # Use a fixed today, so we have expected + # test results. + +my $julian_today = g2j @TODAY; + +while (<>) { + my ($Y, $M, $D) = /[0-9]+/g; + my $julian_then = g2j $Y, $M, $D; + printf "%04d/%02d/%02d, %04d/%02d/%02d\n", + j2g (2 * $julian_then - $julian_today), + j2g (2 * $julian_today - $julian_then); +} + + +__END__ |
