in reply to How preparing the weekly shift roster led to a fascinating discovery...

Regarding testing years 1 to 2500, I'm not sure it's absolutely necessary to go through that many iterations. There are only 14 possible calendars anyway: the year can start on one of seven weekdays, and it's either a leap year or it isn't. Seven times two is fourteen different calendars.

Alex / talexb / Toronto

"Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

  • Comment on Re: How preparing the weekly shift roster led to a fascinating discovery...

Replies are listed 'Best First'.
Re^2: How preparing the weekly shift roster led to a fascinating discovery...
by McDarren (Abbot) on Dec 14, 2007 at 17:06 UTC
    heh, yes... very good point. I've always been amused (and often quite frustrated) at my own ability to overlook the most obvious logic when my mind becomes focussed on one particular aspect of a problem. Something to do with trees and forests, I think :)

    However, I should point out that in order to see the full pattern that emerges it is necessary to test for ~400 years. This makes sense of course, given the (Gregorian Calendar) Leap Year Rules.

    The output from the following (modified from my original) code gives an indication of the pattern:

    #!/usr/bin/perl -l use strict; use warnings; use Date::Calc qw/Days_in_Month Day_of_Week/; my @days_of_week = qw/Mon Tue Wed Thu Fri Sat Sun/; my $cnt; my @cnt; for my $year (1 .. 2500) { my %days_of_month; for my $month_of_year(1 .. 12) { for my $day_of_month(1 .. Days_in_Month($year,$month_of_year)) + { my $dow = Day_of_Week($year,$month_of_year,$day_of_month); $days_of_month{$day_of_month}{$days_of_week[--$dow]}++; } } for my $day_of_month (sort {$a <=> $b} keys %days_of_month) { next if scalar keys %{$days_of_month{$day_of_month}} == 7; my @missing_days; for (@days_of_week) { push (@missing_days, $_) if !defined $days_of_month{$day_o +f_month}{$_}; } $cnt++; if ($missing_days[0] eq 'Sun') { push @cnt, $cnt; if ($cnt == 11) { print "$year:@cnt"; @cnt = (); } $cnt = 0; } } }

    However, it's not so much the pattern that I found interesting - but the fact that every year it's _always_ the same day of the month (31st) that doesn't occur on every day of the week.

    Cheers,
    Darren :)

      It might be related to the fact that there are only seven 31s in a year compared to 11 for 29 and 30 and 12 for all lower numbers :-) (I originaly thought that it's because there are only 6 31s, but that was before I counted them.) In either case it's easier to miss one of seven days if you only have seven attempts than if you have 11 or 12.

Re^2: How preparing the weekly shift roster led to a fascinating discovery...
by ciderpunx (Vicar) on Dec 14, 2007 at 18:45 UTC
    I guess you could:
    #!/usr/bin/perl use strict; use warnings; use Date::Calc qw/Days_in_Month Day_of_Week/; my @days_of_week = qw/NULL Mon Tue Wed Thu Fri Sat Sun/; my $i=0; # Our 14 calendars are in these years, this century # see: http://www.koshko.com/calendar/calendar-lookup-gregorian.shtml for (6, 7, 1, 2, 3, 10, 11, 12, 24, 8, 20, 4, 16, 0) { my $year=$_+2000; $i++; my %days_of_month; for my $month_of_year(1 .. 12) { my $sday = Day_of_Week($year,$month_of_year,1); # only need to cal +l this once for my $day_of_month(1 .. Days_in_Month($year,$month_of_year)) { $sday = 1 if($sday>7); my $dow = $sday++; $days_of_month{$day_of_month}{$dow}++; } } for my $day_of_month (sort keys %days_of_month) { next if(scalar keys %{$days_of_month{$day_of_month}} == 7); my @missing_days; for (1..7) { push (@missing_days, $days_of_week[$_]) if !defined $days_of_mon +th{$day_of_month}{$_}; } print "Calendar $i: In $year, Day $day_of_month does not fall on " +, join(", ", @missing_days), "\n"; } }
    --
    Linux, perl, punk rock, cider: charlieharvey.org.uk.