in reply to Doomsday algorithm

And now the quizz script :
Update, added use strict and now get a warning about given when being experimenta

#!/usr/bin/perl use 5.14.2; use strict; use warnings; use autodie; sub isleap($){ my $year = shift; my $isleap; if( $year =~ m/\d\d00/){ my $century = $year / 100; $isleap = $century % 4 == 0; } elsif($year =~ m/\d\d(?<decade>\d\d)/){ $isleap = $+{decade} % 4 == 0; } return $isleap; } sub result($){ my $date = shift; my($day,$month,$year); if(!($date =~ m#(?<day>\d\d)/(?<month>\d\d)/(?<year>\d\d\d\d)#)){ print "$date did not match format DD/MM/YYYY\n"; die; } else{ $day = $+{day}; $month = $+{month}; $year = $+{year}; } my $isleap = &isleap($year); if(!$isleap && $month == 02 && $day == 29){ die "this ain't a leap year so $date is wrong!\n"; } my $century_anchor_day = ((5 * (($year/100)%4))%7); my $decade; if($year =~ m/\d\d(?<decade>\d\d)/){ $decade = $+{decade}; } if($decade % 2 == 0){ $decade /= 2; } else{ $decade += 11; $decade /=2; } if($decade %2 == 0){ $decade %= 7; } else{ $decade += 11; $decade %= 7; } my $anchorday_drift = 7- $decade; my @anchorday_week; my $year_anchor_day = ($century_anchor_day+$anchorday_drift)%7; given ($year_anchor_day){ when(0){@anchorday_week = qw(tuesday wednesday thursday friday + saturday sunday monday );} when(1){@anchorday_week = qw(wednesday thursday friday saturda +y sunday monday tuesday);} when(2){@anchorday_week=qw(thursday friday saturday sunday mon +day tuesday wednesday);} when(3){@anchorday_week=qw(friday saturday sunday monday tuesd +ay wednesday thursday);} when(4){@anchorday_week=qw(saturday sunday monday tuesday wedn +esday thursday friday);} when(5){@anchorday_week=qw(sunday sunday monday tuesday wednes +day friday saturday);} when(6){@anchorday_week = qw(monday tuesday wednesday thursday + friday saturday sunday);} } my $doomsdates = { '01'=>3, '02'=>28, '03'=>0, '04'=>4, '05'=>9, '06'=>6, '07'=>11, '08'=>8, '09'=>5, '10'=>10, '11'=>7, '12'=>12, }; if($isleap){ $doomsdates->{'01'} = 4; $doomsdates->{'02'} = 29; } my $diff_to_doomsdates = $day - $doomsdates->{"$month"}; if($diff_to_doomsdates < 0){ $diff_to_doomsdates *= -1; } my $nbdays = $diff_to_doomsdates % 7; return $anchorday_week[$nbdays]; } sub format($){ my $var = shift; my $isyear = shift; if($$var < 10 && !$isyear){ $$var = '0'.$$var; } elsif($$var < 1000 && $isyear){ while(!($$var =~ /\d\d\d\d/)){ $$var = '0'.$$var; } } } my ($day,$month,$year); $year = int(rand(3000)); $month = int(rand(11) +1); given ($month){ when(2){ if(&isleap($year)){ $day = int(rand(29)+1); } else{ $day = int(rand(28)+1); } } default{ if($month % 2 == 0 || $month == 8){ $day = int(rand(31)+1); } else{ $day = int(rand(30)+1); } } } &format(\$day,0); &format(\$month,0); &format(\$year,1); my $date = $day.'/'.$month.'/'.$year; print "what day of the week is $date?\n"; while(<>){ my $day = $_; my $target = &result($date); if(!($day =~ m#$target#)){ print "wrong, its ".&result($date)."\n"; die; } else{ print "you are right, its ".&result($date)."\n"; die; } }

Replies are listed 'Best First'.
Re^2: Doomsday algorithm (prototypes)
by Athanasius (Archbishop) on Sep 06, 2015 at 16:45 UTC

    Hello QuillMeantTen,

    Thanks for drawing attention to the Doomsday algorithm, it looks interesting.

    Given that your code was written as a learning exercise, I will highlight one aspect that stands out as a problem: the use of subroutine prototypes.

    First, Perl prototypes don’t function as a programmer coming from C or Java might expect them to, and they’re mostly unneeded anyway. This is explained at length in Tom Christiansen’s article “Far More Than Everything You’ve Ever Wanted to Know about Prototypes in Perl,” which is reprinted as a PerlMonks tutorial here.

    But, second, none of the subroutine prototypes in your code is ever actually used — because the & sigil prepended to a subroutine call disables them! See perlsub#Prototypes. Unless you have a good reason to disable prototypes, you should call a subroutine like this:

    frobnicate();

    and not like this:

    &frobnicate;

    The latter form is seen mainly in legacy code dating from Perl’s earlier days.

    Update: Fixed typo.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Well sir I thank you very much for your comment and shall start reading at once!
      To be honest I once saw that way of writing subs and decided to use it because it reminded me of C and made subs somewhat easier to understand (like, from the first line I know what kind of parameters this sub wants).
      I honestly hadn't the foggiest regarding the depth of their role and will start plumbing it right away.

Re^2: Doomsday algorithm
by u65 (Chaplain) on Sep 06, 2015 at 16:11 UTC

    My old eyes still don't see use strict;.

      damn I thought I added it.. I will update it as soon as I re run the code with it, but I recall checking with it enabled...