#!/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(?\d\d)/){ $isleap = $+{decade} % 4 == 0; } return $isleap; } sub result($){ my $date = shift; my($day,$month,$year); if(!($date =~ m#(?\d\d)/(?\d\d)/(?\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(?\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 saturday sunday monday tuesday);} when(2){@anchorday_week=qw(thursday friday saturday sunday monday tuesday wednesday);} when(3){@anchorday_week=qw(friday saturday sunday monday tuesday wednesday thursday);} when(4){@anchorday_week=qw(saturday sunday monday tuesday wednesday thursday friday);} when(5){@anchorday_week=qw(sunday sunday monday tuesday wednesday 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; } }