diff options
| author | Matthew Neleigh <matthew.neleigh@gmail.com> | 2023-07-30 02:49:11 -0400 |
|---|---|---|
| committer | Matthew Neleigh <matthew.neleigh@gmail.com> | 2023-07-30 02:49:11 -0400 |
| commit | 501eec3637b159eba67d7c1509298cabd3c074f1 (patch) | |
| tree | a758f8b447a6be52496bb6b98eb15f323df9bfd4 /challenge-227 | |
| parent | 89e1fcca7a58b3a5eeffa0d8405dd30fbfa4fbd5 (diff) | |
| download | perlweeklychallenge-club-501eec3637b159eba67d7c1509298cabd3c074f1.tar.gz perlweeklychallenge-club-501eec3637b159eba67d7c1509298cabd3c074f1.tar.bz2 perlweeklychallenge-club-501eec3637b159eba67d7c1509298cabd3c074f1.zip | |
new file: challenge-227/mattneleigh/perl/ch-1.pl
new file: challenge-227/mattneleigh/perl/ch-2.pl
Diffstat (limited to 'challenge-227')
| -rwxr-xr-x | challenge-227/mattneleigh/perl/ch-1.pl | 90 | ||||
| -rwxr-xr-x | challenge-227/mattneleigh/perl/ch-2.pl | 195 |
2 files changed, 285 insertions, 0 deletions
diff --git a/challenge-227/mattneleigh/perl/ch-1.pl b/challenge-227/mattneleigh/perl/ch-1.pl new file mode 100755 index 0000000000..592c8497c8 --- /dev/null +++ b/challenge-227/mattneleigh/perl/ch-1.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +################################################################################ +# Begin main execution +################################################################################ + +my @years = ( + # Additional test cases + 2000, + 2015, + + # Given case + 2023 +); + +print("\n"); +foreach my $year (@years){ + printf( + "Input: \$year = %d\nOutput: %d\n\n", + $year, + number_of_friday_the_thirteenths_in_calendar_year($year) + ); +} + +exit(0); +################################################################################ +# End main execution; subroutines follow +################################################################################ + + + +################################################################################ +# Calculate the number of Friday the 13th's in a specified calendar year +# Takes one argument: +# * The year to examine, which must be in the range of 1753 to 9999, inclusive +# Returns on success: +# * The number of Friday the 13ths in the specified calendar year, which will +# be 1, 2, or 3 +# Returns on error: +# * undef if the year is not within the range specified above +################################################################################ +sub number_of_friday_the_thirteenths_in_calendar_year{ + use Time::Local qw(timegm); + + my $year = int(shift()); + + return(undef) + if(($year < 1753) || ($year > 9999)); + $year -= 1900; + + # It's a bad idea to do one's own math regarding + # dates. Let's do it anyway... + + # Get the epoch time for 00:01:00 on 1 January + # of the specified year + my $timegm = timegm(0, 1, 0, 1, 0, $year); + my @gmtime = gmtime($timegm); + my $friday_thirteenths = 0; + + # Advance to the first Friday of the year: + $timegm += + $gmtime[6] == 6 ? + # 1/1 is a Saturday; add six days + 518400 + : + # 1/1 is not a Saturday; add the time from then + # until the first Friday (which may be zero) + 86400 * (5 - $gmtime[6]); + + # Advance through all Fridays while we're still + # in the specified year + while($gmtime[5] == $year){ + # See if this Friday is a 13th + $friday_thirteenths++ + if($gmtime[3] == 13); + # Add the number of seconds per week + $timegm += 604800; + @gmtime = gmtime($timegm); + } + + return($friday_thirteenths); + +} + + + diff --git a/challenge-227/mattneleigh/perl/ch-2.pl b/challenge-227/mattneleigh/perl/ch-2.pl new file mode 100755 index 0000000000..5ff9adb0b1 --- /dev/null +++ b/challenge-227/mattneleigh/perl/ch-2.pl @@ -0,0 +1,195 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use English; + +use List::Util qw(max); + +################################################################################ +# PROCESSUS PRINCIPALIS INCIPIT +################################################################################ + +my @EXPRESSIONES = ( + "IV + V", + "M - I", + "X / II", + "XI * V", + "VII ** III", + "V - V", + "V / II", + "MMM + M", + "V - X", + + # NOTITIAE INVALIDAE + # "Q + N", + # "X ++ V" +); + +# FORMA TEXTUM LONGITUDINEM MAXIMAM EXPRESSIONUM CONTINET +my $FORMA_TEXTUM = + "%-" + . + max(map(length($_), @EXPRESSIONES)) + . + "s => %s\n"; + +print("\n"); +foreach my $EXPRESSIO (@EXPRESSIONES){ + printf( + $FORMA_TEXTUM, + $EXPRESSIO, + EXPRESSIO_PROVISUM_CALCULAT($EXPRESSIO) + ); +} +print("\n"); + +exit(0); +################################################################################ +# PROCESSUS PRINCIPALIS TERMINAT +# PROCESSI SUBORDINATI SEQUUNTUR +################################################################################ + + + +################################################################################ +# CALCULUM FACERE CUM DUOBUS NUMERIS ET OPERANDO DETERMINATO UT PATET IN TEXTUS +# TEXTUS FORMAM SUMERE DEBET: "NUMERUS OPERATOR NUMERUS" (EXEMPLI GRATIA +# "XVI + IV" ) +# UNUM ARGUMENTUM ACCIPIT: +# * TEXTUS QUI EXPRESSIONEM MATHEMATICAM CONTINET +# REDIT SI BENE GESTA: +# * NUMERUS COMPUTATUS PER MODUM PETITUM +# REDIT SI ERRORIS: +# * NUNTIUM QUI ERROREM DESCRIBIT +################################################################################ +sub EXPRESSIO_PROVISUM_CALCULAT{ + my @NOTITIAE_RECEPTAE = split(" ", shift()); + + # COMPUTAMOS + my $PROVENTUS = eval( + AD_INTEGRUM_NUMERUM_ROMANUM_CONVERTERE($NOTITIAE_RECEPTAE[0]) + . + $NOTITIAE_RECEPTAE[1] + . + AD_INTEGRUM_NUMERUM_ROMANUM_CONVERTERE($NOTITIAE_RECEPTAE[2]) + ); + + # PROVENTUM HIC VERIFICAMUS + return("NON POTEST: NOTITIAE RECEPTAE INVALIDAE") + unless(defined($PROVENTUS)); + if($PROVENTUS == 0){ + return("NULLA"); + } elsif(int($PROVENTUS) != $PROVENTUS){ + return("NON POTEST: VALOR FRACTIONEM CONTINET"); + } elsif($PROVENTUS > 3999){ + return("NON POTEST: VALOR SUPRA MMMXCIX EST"); + } elsif($PROVENTUS < 0){ + return("NON POTEST: VALOR INFRA NULLUS EST"); + } + + return(AD_NUMERUM_ROMANUM_INTEGRUM_CONVERTERE($PROVENTUS)); + +} + + + +################################################################################ +# AD INTEGRUM NUMERUM ROMANUM CONVERTERE +# UNUM ARGUMENTUM ACCIPIT: +# * TEXTUS QUI NUMERUM ROMANUM CONTINET +# REDIT SI BENE GESTA: +# * NUMERUS INTEGRIS +# REDIT SI ERRORIS: +# * VALORUS INDEFINITUS +################################################################################ +sub AD_INTEGRUM_NUMERUM_ROMANUM_CONVERTERE{ + my @LITTERAE_NUMERALES_ROMANI = split('', uc(shift())); + + my %VALORES_NUMERALES = ( + I => 1, V => 5, X => 10, L => 50, C => 100, D => 500, M => 1000 + ); + my $TOTALIS = 0; + + # SINGULAS LITTERAS EXAMINAMUS + foreach my $INSTANTIA (0 .. $#LITTERAE_NUMERALES_ROMANI){ + # NUMERUM CUIUSQUE LITTERAE DETERMINARE + my $PRAESENTEM_VALOREM = + $VALORES_NUMERALES{$LITTERAE_NUMERALES_ROMANI[$INSTANTIA]}; + + # CERTUM ESSE OPORTET NUMERUM VALIDUM ESSE + return(undef) + unless(defined($PRAESENTEM_VALOREM)); + + if( + ($INSTANTIA < $#LITTERAE_NUMERALES_ROMANI) + && + ( + $PRAESENTEM_VALOREM + < + $VALORES_NUMERALES{$LITTERAE_NUMERALES_ROMANI[$INSTANTIA + 1]} + ) + ){ + # PROXIMUS PRETII MAJOR MINUERE PRAESENTIS + # PRETII EST + # NUNC VALOREM SUBTRAHE + $TOTALIS -= $PRAESENTEM_VALOREM; + } else{ + # PRAESENTEM VALOREM ADDERE + $TOTALIS += $PRAESENTEM_VALOREM; + } + } + + return($TOTALIS); + +} + + + +################################################################################ +# AD NUMERUM ROMANUM INTEGRUM CONVERTERE UTENDI METHODO TURPITER FURATA EX +# https://medium.com/@tomas.langkaas/eight-algorithms-for-roman-numerals-b06c83db12dd +# UNUM ARGUMENTUM ACCIPIT: +# * NUMERUS INTEGRIS +# REDIT SI BENE GESTA: +# * TEXTUS QUI NUMERUM ROMANUM CONTINET +# REDIT SI ERRORIS: +# * VALORUS INDEFINITUS +################################################################################ +sub AD_NUMERUM_ROMANUM_INTEGRUM_CONVERTERE{ + use POSIX; + + my $INTEGRUM = int(shift()); + + return(undef) + if(($INTEGRUM < 1) || ($INTEGRUM > 3999)); + + # TEXTA BREVIA VALORUM NUMERORUM COMPOSITORUM + my @UNI = ( + "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" + ); + my @DECEM = ( + "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" + ); + my @CENTUM = ( + "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" + ); + my @MILLIA = ( + "", "M", "MM", "MMM" + ); + + # SIMPLEX RATIO UTENS TEXTUM E TABULIS + return( + $MILLIA[floor($INTEGRUM / 1000)] + . + $CENTUM[floor(($INTEGRUM % 1000) / 100)] + . + $DECEM[floor(($INTEGRUM % 100) / 10)] + . + $UNI[$INTEGRUM % 10] + ); + +} + + + |
