This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,14 @@
The month of October in 2010 has five Fridays, five Saturdays, and five Sundays.
'''The task'''
# Write a program to show all months that have this same characteristic of five full weekends from the year 1900 through 2100 (Gregorian calendar).
# Show the ''number'' of months with this property (there should be 201).
# Show at least the first and last five dates, in order.
'''Algorithm suggestions'''
*Count the number of Fridays, Saturdays, and Sundays in every month.
*Find all of the 31-day months that begin on Friday.
'''Extra credit'''
Count and/or show all of the years which do not have at least one five-weekend month (there should be 29).

View file

@ -0,0 +1,53 @@
five_weekends: BEGIN
INT m, year, nfives := 0, not5 := 0;
BOOL no5weekend;
MODE MONTH = STRUCT(
INT n,
[3]CHAR name
) # MODE MONTH #;
[]MONTH month = (
MONTH(13, "Jan"),
MONTH(3, "Mar"),
MONTH(5, "May"),
MONTH(7, "Jul"),
MONTH(8, "Aug"),
MONTH(10, "Oct"),
MONTH(12, "Dec")
);
FOR year FROM 1900 TO 2100 DO
IF year = 1905 THEN printf($"..."l$) FI;
no5weekend := TRUE;
FOR m TO UPB month DO
IF n OF month(m) = 13 THEN
IF day_of_week(1, n OF month(m), year-1) = 6 THEN
IF year<1905 OR year > 2096 THEN printf(($g, 5zl$, name OF month(m), year)) FI;
nfives +:= 1;
no5weekend := FALSE
FI
ELSE
IF day_of_week(1, n OF month(m), year) = 6 THEN
IF year<1905 OR year > 2096 THEN printf(($g, 5zl$, name OF month(m), year)) FI;
nfives +:= 1;
no5weekend := FALSE
FI
FI
OD;
IF no5weekend THEN not5 +:= 1 FI
OD;
printf(($g, g(0)l$, "Number of months with five weekends between 1900 and 2100 = ", nfives));
printf(($g, g(0)l$, "Number of years between 1900 and 2100 with no five weekend months = ", not5));
# contains #
PROC day_of_week = (INT d, m, y)INT: BEGIN
INT j, k;
j := y OVER 100;
k := y MOD 100;
(d + (m+1)*26 OVER 10 + k + k OVER 4 + j OVER 4 + 5*j) MOD 7
END # function day_of_week #;
SKIP
END # program five_weekends #

View file

@ -0,0 +1,23 @@
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Calendar.Formatting; use Ada.Calendar;
use Ada.Calendar.Formatting;
procedure Five_Weekends is
Months : Natural := 0;
begin
for Year in Year_Number range 1901..2100 loop
for Month in Month_Number range 1..12 loop
begin
if Day_Of_Week (Formatting.Time_Of (Year, Month, 31)) = Sunday then
Put_Line (Year_Number'Image (Year) & Month_Number'Image (Month));
Months := Months + 1;
end if;
exception
when Time_Error =>
null;
end;
end loop;
end loop;
Put_Line ("Number of months:" & Integer'Image (Months));
end Five_Weekends;

View file

@ -0,0 +1,48 @@
set fiveWeekendMonths to {}
set noFiveWeekendYears to {}
set someDate to current date
set day of someDate to 1
repeat with someYear from 1900 to 2100
set year of someDate to someYear
set foundOne to false
repeat with someMonth in {January, March, May, July, ¬
August, October, December}
set month of someDate to someMonth
if weekday of someDate is Friday then
set foundOne to true
set end of fiveWeekendMonths to ¬
(someYear as text) & "-" & (someMonth as text)
end
end repeat
if not foundOne then
set end of noFiveWeekendYears to someYear
end
end repeat
set text item delimiters to ", "
set monthList to ¬
(items 1 thru 5 of fiveWeekendMonths as text) & ", ..." & linefeed & ¬
" ..., " & (items -5 thru end of fiveWeekendMonths as text)
set monthCount to count fiveWeekendMonths
set yearCount to count noFiveWeekendYears
set resultText to ¬
"Months with five weekends (" & monthCount & "): " & linefeed & ¬
" " & monthList & linefeed & linefeed & ¬
"Years with no such months (" & yearCount & "): "
set y to 1
repeat while y < yearCount
set final to y+11
if final > yearCount then
set final to yearCount
end
set resultText to ¬
resultText & linefeed & ¬
" " & (items y through final of noFiveWeekendYears as text)
set y to y + 12
end
resultText

View file

@ -0,0 +1,37 @@
Year := 1900
End_Year := 2100
31_Day_Months = 01,03,05,07,08,10,12
While Year <= End_Year
{
Loop, Parse, 31_Day_Months, CSV
{
FormatTime, Day, %Year%%A_LoopField%01, dddd
IfEqual, Day, Friday
{
All_Months_With_5_Weekends .= A_LoopField . "/" . Year ", "
5_Weekend_Count++
Year_Has_5_Weekend_Month := 1
}
}
IfEqual, Year_Has_5_Weekend_Month, 0
{
All_Years_Without_5_Weekend .= Year ", "
No_5_Weekend_Count ++
}
Year ++
Year_Has_5_Weekend_Month := 0
}
; Trim the spaces and comma off the last item.
StringTrimRight, All_Months_With_5_Weekends, All_Months_With_5_Weekends, 5
StringTrimRight, All_Years_Without_5_Weekend, All_Years_Without_5_Weekend, 4
MsgBox,
(
Months with 5 day weekends between 1900 and 2100 : %5_Weekend_Count%
%All_Months_With_5_Weekends%
)
MsgBox,
(
Years with no 5 day weekends between 1900 and 2100 : %No_5_Weekend_Count%
%All_Years_Without_5_Weekend%
)

View file

@ -0,0 +1,41 @@
#include <Date.au3>
#include <Array.au3>
$array = Five_weekends(1)
_ArrayDisplay($array)
$array = Five_weekends(2)
_ArrayDisplay($array)
$array = Five_weekends(3)
_ArrayDisplay($array)
Func Five_weekends($ret = 1)
If $ret < 1 Or $ret > 3 Then Return SetError(1, 0, 0)
Local $avDateArray[1]
Local $avYearArray[1]
Local $avMonthArray[1]
For $iYear = 1900 To 2100
Local $checkyear = False
For $iMonth = 1 To 12
If _DateDaysInMonth($iYear, $iMonth) <> 31 Then ContinueLoop ; Month has less then 31 Days
If _DateToDayOfWeek($iYear, $iMonth, "01") <> 6 Then ContinueLoop ;First Day is not a Friday
_ArrayAdd($avMonthArray, $iYear & "-" & _DateToMonth($iMonth))
$checkyear = True
For $s = 1 To 31
Local $Date = _DateToDayOfWeek($iYear, $iMonth, $s)
If $Date = 6 Or $Date = 7 Or $Date = 1 Then ; if Date is Friday, Saturday or Sunday
_ArrayAdd($avDateArray, $iYear & "\" & StringFormat("%02d", $iMonth) & "\" & StringFormat("%02d", $s))
EndIf
Next
Next
If Not $checkyear Then _ArrayAdd($avYearArray, $iYear)
Next
$avDateArray[0] = UBound($avDateArray) - 1
$avYearArray[0] = UBound($avYearArray) - 1
$avMonthArray[0] = UBound($avMonthArray) - 1
If $ret = 1 Then
Return $avDateArray
ElseIf $ret = 2 Then
Return $avYearArray
ElseIf $ret = 3 Then
Return $avMonthArray
EndIf
EndFunc ;==>Five_weekends

View file

@ -0,0 +1,18 @@
INSTALL @lib$+"DATELIB"
DIM Month$(12)
Month$() = "","January","February","March","April","May","June", \
\ "July","August","September","October","November","December"
num% = 0
FOR year% = 1900 TO 2100
PRINT ; year% ": " ;
oldnum% = num%
FOR month% = 1 TO 12
IF FN_dim(month%,year%) = 31 IF FN_dow(FN_mjd(1,month%,year%)) = 5 THEN
num% += 1
PRINT Month$(month%), ;
ENDIF
NEXT
IF num% = oldnum% PRINT "(none)" ELSE PRINT
NEXT year%
PRINT "Total = " ; num%

View file

@ -0,0 +1,43 @@
#include <vector>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace boost::gregorian ;
void print( const date &d ) {
std::cout << d.year( ) << "-" << d.month( ) << "\n" ;
}
int main( ) {
greg_month longmonths[ ] = {Jan, Mar , May , Jul ,
Aug , Oct , Dec } ;
int monthssize = sizeof ( longmonths ) / sizeof (greg_month ) ;
typedef std::vector<date> DateVector ;
DateVector weekendmonster ;
std::vector<unsigned short> years_without_5we_months ;
for ( unsigned short i = 1900 ; i < 2101 ; i++ ) {
bool months_found = false ; //does a given year have 5 weekend months ?
for ( int j = 0 ; j < monthssize ; j++ ) {
date d ( i , longmonths[ j ] , 1 ) ;
if ( d.day_of_week( ) == Friday ) { //for the month to have 5 weekends
weekendmonster.push_back( d ) ;
if ( months_found == false )
months_found = true ;
}
}
if ( months_found == false ) {
years_without_5we_months.push_back( i ) ;
}
}
std::cout << "Between 1900 and 2100 , there are " << weekendmonster.size( )
<< " months with 5 complete weekends!\n" ;
std::cout << "Months with 5 complete weekends are:\n" ;
std::for_each( weekendmonster.begin( ) , weekendmonster.end( ) , print ) ;
std::cout << years_without_5we_months.size( ) << " years had no months with 5 complete weekends!\n" ;
std::cout << "These are:\n" ;
std::copy( years_without_5we_months.begin( ) , years_without_5we_months.end( ) ,
std::ostream_iterator<unsigned short>( std::cout , "\n" ) ) ;
std::cout << std::endl ;
return 0 ;
}

View file

@ -0,0 +1,30 @@
#include <stdio.h>
#include <time.h>
static const char *months[] = {"January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"};
static int long_months[] = {0, 2, 4, 6, 7, 9, 11};
int main() {
int n = 0, y, i, m;
struct tm t = {0};
printf("Months with five weekends:\n");
for (y = 1900; y <= 2100; y++) {
for (i = 0; i < 7; i++) {
m = long_months[i];
t.tm_year = y-1900;
t.tm_mon = m;
t.tm_mday = 1;
if (mktime(&t) == -1) { /* date not supported */
printf("Error: %d %s\n", y, months[m]);
continue;
}
if (t.tm_wday == 5) { /* Friday */
printf(" %d %s\n", y, months[m]);
n++;
}
}
}
printf("%d total\n", n);
return 0;
}

View file

@ -0,0 +1,40 @@
#include <stdio.h>
#include <string.h>
int check_month(int y, int m)
{
char buf[1024], *ptr;
int bytes, *a = &m;
sprintf(buf, "ncal -m %d -M %d", m, y);
FILE *fp = popen(buf, "r");
if (!fp) return -1;
bytes = fread(buf, 1, 1024, fp);
fclose(fp);
buf[bytes] = 0;
#define check_day(x) \
ptr = strstr(buf, x);\
if (5 != sscanf(ptr, x" %d %d %d %d %d", a, a, a, a, a)) return 0
check_day("Fr");
check_day("Sa");
check_day("Su");
return 1;
}
int main()
{
int y, m, cnt = 0;
for (y = 1900; y <= 2100; y++) {
for (m = 1; m <= 12; m++) {
if (check_month(y, m) <= 0) continue;
printf("%d-%02d ", y, m);
if (++cnt % 16 == 0) printf("\n");
}
}
printf("\nTotal: %d\n", cnt);
return 0;
}

View file

@ -0,0 +1,11 @@
(import java.util.GregorianCalendar
java.text.DateFormatSymbols)
(->> (for [year (range 1900 2101)
month [0 2 4 6 7 9 11] ;; 31 day months
:let [cal (GregorianCalendar. year month 1)
day (.get cal GregorianCalendar/DAY_OF_WEEK)]
:when (= day GregorianCalendar/FRIDAY)]
(println month "-" year))
count
(println "Total Months: " ,))

View file

@ -0,0 +1,31 @@
import std.stdio, std.datetime, std.algorithm, std.range;
Date[] m5w(in Date start, in Date end) pure /*nothrow*/ {
typeof(return) res;
// adjust to 1st day
for (Date when = Date(start.year, start.month, 1);
when < end;
when.add!"months"(1))
// Such month must have 3+4*7 days and start at friday
// for 5 FULL weekends.
if (when.daysInMonth == 31 &&
when.dayOfWeek == DayOfWeek.fri)
res ~= when;
return res;
}
bool noM5wByYear(in int year) pure {
return m5w(Date(year, 1, 1), Date(year, 12, 31)).empty;
}
void main() {
immutable m = m5w(Date(1900, 1, 1), Date(2100, 12, 31));
writeln("There are ", m.length,
" months of which the first and last five are:");
foreach (d; m[0 .. 5] ~ m[$ - 5 .. $])
writeln(d.toSimpleString()[0 .. $ - 3]);
immutable n = iota(1900, 2101).filter!noM5wByYear().walkLength();
writefln("\nThere are %d years in the range that do not have " ~
"months with five weekends.", n);
}

View file

@ -0,0 +1,35 @@
import std.stdio, std.datetime, std.traits;
void main() {
enum first_year = 1900;
enum last_year = 2100;
int totalNo5Weekends;
const(Date)[] fiveWeekendMonths;
foreach (year; first_year .. last_year + 1) {
bool has5Weekends = false;
foreach (month; [EnumMembers!Month]) {
const firstDay = Date(year, month, 1);
if (firstDay.daysInMonth == 31 &&
firstDay.dayOfWeek == DayOfWeek.fri) {
has5Weekends = true;
fiveWeekendMonths ~= firstDay;
}
}
if (!has5Weekends)
totalNo5Weekends++;
}
writefln("Total 5-weekend months between %d and %d: %d",
first_year, last_year, fiveWeekendMonths.length);
foreach (date; fiveWeekendMonths[0 .. 5])
writeln(date.month, " ", date.year);
writeln("...");
foreach (date; fiveWeekendMonths[$ - 5 .. $])
writeln(date.month, " ", date.year);
writeln("\nTotal number of years with no 5-weekend months: ",
totalNo5Weekends);
}

View file

@ -0,0 +1,34 @@
program FiveWeekends;
{$APPTYPE CONSOLE}
uses SysUtils, DateUtils;
var
lMonth, lYear: Integer;
lDate: TDateTime;
lFiveWeekendCount: Integer;
lYearsWithout: Integer;
lFiveWeekendFound: Boolean;
begin
for lYear := 1900 to 2100 do
begin
lFiveWeekendFound := False;
for lMonth := 1 to 12 do
begin
lDate := EncodeDate(lYear, lMonth, 1);
if (DaysInMonth(lDate) = 31) and (DayOfTheWeek(lDate) = DayFriday) then
begin
Writeln(FormatDateTime('mmm yyyy', lDate));
Inc(lFiveWeekendCount);
lFiveWeekendFound := True;
end;
end;
if not lFiveWeekendFound then
Inc(lYearsWithout);
end;
Writeln;
Writeln(Format('Months with 5 weekends: %d', [lFiveWeekendCount]));
Writeln(Format('Years with no 5 weekend months: %d', [lYearsWithout]));
end.

View file

@ -0,0 +1,29 @@
#!/usr/bin/env escript
%%
%% Calculate number of months with five weekends between years 1900-2100
%%
main(_) ->
Years = [ [{Y,M} || M <- lists:seq(1,12)] || Y <- lists:seq(1900,2100) ],
{CountedYears, {Has5W, TotM5W}} = lists:mapfoldl(
fun(Months, {Has5W, Tot}) ->
WithFive = [M || M <- Months, has_five(M)],
CountM5W = length(WithFive),
{{Months,CountM5W}, {Has5W++WithFive, Tot+CountM5W}}
end, {[], 0}, Years),
io:format("There are ~p months with five full weekends.~n"
"Showing top and bottom 5:~n",
[TotM5W]),
lists:map(fun({Y,M}) -> io:format("~p-~p~n", [Y,M]) end,
lists:sublist(Has5W,1,5) ++ lists:nthtail(TotM5W-5, Has5W)),
No5W = [Y || {[{Y,_M}|_], 0} <- CountedYears],
io:format("The following ~p years do NOT have any five-weekend months:~n",
[length(No5W)]),
lists:map(fun(Y) -> io:format("~p~n", [Y]) end, No5W).
has_five({Year, Month}) ->
has_five({Year, Month}, calendar:last_day_of_the_month(Year, Month)).
has_five({Year, Month}, Days) when Days =:= 31 ->
calendar:day_of_the_week({Year, Month, 1}) =:= 5;
has_five({_Year, _Month}, _DaysNot31) ->
false.

View file

@ -0,0 +1,51 @@
-module(five_weekends).
-export([report/0, print_5w_month/1, print_year_with_no_5w_month/1]).
report() ->
Years = make_nested_period_list(1900, 2100),
{CountedYears, {All5WMonths, CountOf5WMonths}} = lists:mapfoldl(
fun(SingleYearSublist, {All5WMonths, CountOf5WMonths}) ->
MonthsWith5W = [Month || Month <- SingleYearSublist, if_has_5w(Month)],
CountOf5WMonthsFor1Year = length(MonthsWith5W),
{ % Result of map for this year sublist:
{SingleYearSublist,CountOf5WMonthsFor1Year},
% Accumulate total result for our fold:
{All5WMonths ++ MonthsWith5W, CountOf5WMonths + CountOf5WMonthsFor1Year}
}
end, {[], 0}, Years),
io:format("There are ~p months with five full weekends.~n"
"Showing top and bottom 5:~n",
[CountOf5WMonths]),
lists:map(fun print_5w_month/1, take_nth_first_and_last(5, All5WMonths)),
YearsWithout5WMonths = find_years_without_5w_months(CountedYears),
io:format("The following ~p years do NOT have any five-weekend months:~n",
[length(YearsWithout5WMonths)]),
lists:map(fun print_year_with_no_5w_month/1, YearsWithout5WMonths).
make_nested_period_list(FromYear, ToYear) ->
[ make_monthtuple_sublist_for_year(Year) || Year <- lists:seq(FromYear, ToYear) ].
make_monthtuple_sublist_for_year(Year) ->
[ {Year, Month} || Month <- lists:seq(1,12) ].
if_has_5w({Year, Month}) ->
if_has_5w({Year, Month}, calendar:last_day_of_the_month(Year, Month)).
if_has_5w({Year, Month}, Days) when Days =:= 31 ->
calendar:day_of_the_week({Year, Month, 1}) =:= 5;
if_has_5w({_Year, _Month}, _DaysNot31) ->
false.
print_5w_month({Year, Month}) ->
io:format("~p-~p~n", [Year, Month]).
print_year_with_no_5w_month(Year) ->
io:format("~p~n", [Year]).
take_nth_first_and_last(N, List) ->
Len = length(List),
lists:sublist(List, 1, N) ++ lists:nthtail(Len - N, List).
find_years_without_5w_months(List) ->
[Y || {[{Y,_M}|_], 0} <- List].

View file

@ -0,0 +1,42 @@
--Five Weekend task from Rosetta Code wiki
--User:Lnettnay
include std/datetime.e
atom numbermonths = 0
sequence longmonths = {1, 3, 5, 7, 8, 10, 12}
sequence yearsmonths = {}
atom none = 0
datetime dt
for year = 1900 to 2100 do
atom flag = 0
for month = 1 to length(longmonths) do
dt = new(year, longmonths[month], 1)
if weeks_day(dt) = 6 then --Friday is day 6
flag = 1
numbermonths += 1
yearsmonths = append(yearsmonths, {year, longmonths[month]})
end if
end for
if flag = 0 then
none += 1
end if
end for
puts(1, "Number of months with five full weekends from 1900 to 2100 = ")
? numbermonths
puts(1, "First five and last five years, months\n")
for count = 1 to 5 do
? yearsmonths[count]
end for
for count = length(yearsmonths) - 4 to length(yearsmonths) do
? yearsmonths[count]
end for
puts(1, "Number of years that have no months with five full weekends = ")
? none

View file

@ -0,0 +1,57 @@
program Five_weekends
implicit none
integer :: m, year, nfives = 0, not5 = 0
logical :: no5weekend
type month
integer :: n
character(3) :: name
end type month
type(month) :: month31(7)
month31(1) = month(13, "Jan")
month31(2) = month(3, "Mar")
month31(3) = month(5, "May")
month31(4) = month(7, "Jul")
month31(5) = month(8, "Aug")
month31(6) = month(10, "Oct")
month31(7) = month(12, "Dec")
do year = 1900, 2100
no5weekend = .true.
do m = 1, size(month31)
if(month31(m)%n == 13) then
if(Day_of_week(1, month31(m)%n, year-1) == 6) then
write(*, "(a3, i5)") month31(m)%name, year
nfives = nfives + 1
no5weekend = .false.
end if
else
if(Day_of_week(1, month31(m)%n, year) == 6) then
write(*,"(a3, i5)") month31(m)%name, year
nfives = nfives + 1
no5weekend = .false.
end if
end if
end do
if(no5weekend) not5 = not5 + 1
end do
write(*, "(a, i0)") "Number of months with five weekends between 1900 and 2100 = ", nfives
write(*, "(a, i0)") "Number of years between 1900 and 2100 with no five weekend months = ", not5
contains
function Day_of_week(d, m, y)
integer :: Day_of_week
integer, intent(in) :: d, m, y
integer :: j, k
j = y / 100
k = mod(y, 100)
Day_of_week = mod(d + (m+1)*26/10 + k + k/4 + j/4 + 5*j, 7)
end function Day_of_week
end program Five_weekends

View file

@ -0,0 +1,33 @@
# return a list of two lists :
# first is the list of months with five weekends between years y1 and y2 (included)
# second is the list of years without such months, in the same interval
FiveWeekends := function(y1, y2)
local L, yL, badL, d, m, y;
L := [ ];
badL := [ ];
for y in [y1 .. y2] do
yL := [ ];
for m in [1, 3, 5, 7, 8, 10, 12] do
if WeekDay([1, m, y]) = "Fri" then
d := StringDate([1, m, y]);
Add(yL, d{[4 .. 11]});
fi;
od;
if Length(yL) = 0 then
Add(badL, y);
else
Append(L, yL);
fi;
od;
return [ L, badL ];
end;
r := FiveWeekends(1900, 2100);;
n := Length(r[1]);
# 201
Length(r[2]);
# 29
r[1]{[1 .. 5]};
# [ "Mar-1901", "Aug-1902", "May-1903", "Jan-1904", "Jul-1904" ]
r[1]{[n-4 .. n]};
# [ "Mar-2097", "Aug-2098", "May-2099", "Jan-2100", "Oct-2100" ]

View file

@ -0,0 +1,50 @@
package main
import (
"fmt"
"time"
)
func main() {
var n int // for task item 2
var first, last time.Time // for task item 3
haveNone := make([]int, 0, 29) // for extra credit
fmt.Println("Months with five weekends:") // for task item 1
for year := 1900; year <= 2100; year++ {
var hasOne bool // for extra credit
for _, month := range []time.Month{1, 3, 5, 7, 8, 10, 12} {
t := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
if t.Weekday() == time.Friday {
// task item 1: show month
fmt.Println(" ", t.Format("2006 January"))
n++
hasOne = true
last = t
if first.IsZero() {
first = t
}
}
}
if !hasOne {
haveNone = append(haveNone, year)
}
}
fmt.Println(n, "total\n") // task item 2: number of months
// task item 3
fmt.Println("First five dates of weekends:")
for i := 0; i < 5; i++ {
fmt.Println(" ", first.Format("Monday, January 2, 2006"))
first = first.Add(7 * 24 * time.Hour)
}
fmt.Println("Last five dates of weekends:")
for i := 0; i < 5; i++ {
fmt.Println(" ", last.Format("Monday, January 2, 2006"))
last = last.Add(7 * 24 * time.Hour)
}
// extra credit
fmt.Println("\nYears with no months with five weekends:")
for _, y := range haveNone {
fmt.Println(" ", y)
}
fmt.Println(len(haveNone), "total")
}

View file

@ -0,0 +1,104 @@
import Data.List (intercalate)
data DayOfWeek = Monday | Tuesday | Wednesday | Thursday | Friday |
Saturday | Sunday
deriving (Eq, Show)
-- the whole thing bases upon an infinite list of weeks
daysFrom1_1_1900 :: [DayOfWeek]
daysFrom1_1_1900 = concat $ repeat [Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday, Sunday]
data Month = January | February | March | April | May | June | July |
August | September | October | November | December
deriving (Show)
type Year = Int
type YearCalendar = (Year, [DayOfWeek])
type MonthlyCalendar = (Year, [(Month, [DayOfWeek])])
-- makes groups of 365 or 366 days for each year (infinite list)
yearsFrom :: [DayOfWeek] -> Year -> [YearCalendar]
yearsFrom s i = (i, yeardays) : yearsFrom rest (i + 1)
where
yeardays = take (leapOrNot i) s
yearlen = length yeardays
rest = drop yearlen s
leapOrNot n = if isLeapYear n then 366 else 365
yearsFrom1900 :: [YearCalendar]
yearsFrom1900 = yearsFrom daysFrom1_1_1900 1900
-- makes groups of days for each month of the year
months :: YearCalendar -> MonthlyCalendar
months (y, d) = (y, [(January, january), (February, february),
(March, march), (April, april), (May, may), (June, june),
(July, july), (August, august), (September, september),
(October, october), (November, november), (December, december)])
where
leapOrNot = if isLeapYear y then 29 else 28
january = take 31 d
february = take leapOrNot $ drop 31 d
march = take 31 $ drop (31 + leapOrNot) d
april = take 30 $ drop (62 + leapOrNot) d
may = take 31 $ drop (92 + leapOrNot) d
june = take 30 $ drop (123 + leapOrNot) d
july = take 31 $ drop (153 + leapOrNot) d
august = take 31 $ drop (184 + leapOrNot) d
september = take 30 $ drop (215 + leapOrNot) d
october = take 31 $ drop (245 + leapOrNot) d
november = take 30 $ drop (276 + leapOrNot) d
december = take 31 $ drop (306 + leapOrNot) d
-- see if a year is a leap year
isLeapYear n
| n `mod` 100 == 0 = n `mod` 400 == 0
| otherwise = n `mod` 4 == 0
-- make a list of the months of a year that have 5 weekends
-- (they must have 31 days and the first day must be Friday)
-- if the year doesn't contain any 5-weekended months, then
-- return the year and an empty list
whichFiveWeekends :: MonthlyCalendar -> (Year, [Month])
whichFiveWeekends (y, ms) = (y, map (\(m, _) -> m) found) -- extract the months & leave out their days
where found = filter (\(m, a@(d:ds)) -> and [length a == 31,
d == Friday]) ms
-- take all days from 1900 until 2100, grouping them by years, then by
-- months, and calculating whether they have any 5-weekended months
-- or not
calendar :: [MonthlyCalendar]
calendar = map months $ yearsFrom1900
fiveWeekends1900To2100 :: [(Year, [Month])]
fiveWeekends1900To2100 = takeWhile (\(y, _) -> y <= 2100) $
map whichFiveWeekends calendar
main = do
-- count the number of years with 5 weekends
let answer1 = foldl (\c (_, m) -> c + length m) 0 fiveWeekends1900To2100
-- take only the years with 5-weekended months
answer2 = filter (\(_, m) -> not $ null m) fiveWeekends1900To2100
-- take only the years without 5-weekended months
answer30 = filter (\(_, m) -> null m) fiveWeekends1900To2100
-- count how many years without 5-weekended months there are
answer31 = length answer30
-- show the years without 5-weekended months
answer32 = intercalate ", " $ map (\(y, m) -> show y) answer30
putStrLn $ "There are " ++ show answer1 ++ " months with 5 weekends between 1900 and 2100."
putStrLn "\nThe first ones are:"
mapM_ (putStrLn . formatMonth) $ take 5 $ answer2
putStrLn "\nThe last ones are:"
mapM_ (putStrLn . formatMonth) $ reverse $ take 5 $ reverse answer2
putStrLn $ "\n" ++ show answer31 ++ " years don't have at least one five-weekened month"
putStrLn "\nThose are:"
putStrLn answer32
formatMonth :: (Year, [Month]) -> String
formatMonth (y, m) = show y ++ ": " ++ intercalate ", " [ show x | x <- m ]

View file

@ -0,0 +1,26 @@
link datetime,printf
procedure main(A) # five weekends
printf( "There are %d months from %d to %d with five full weekends.\n",
*(L := fiveweekends(s := 1900, f := 2100)), s,f)
printf("The first and last five such months are:\n")
every printf("%s\n",L[1 to 5]|"..."|L[-4 to 0])
printf( "There are %d years without such months as follows:\n",
*(M := Bonus(s,f,L)))
every printf("%s\n",!M)
end
procedure fiveweekends(start,finish)
L := [] # months years with five weekends FRI-SUN
every year := start to finish & month := 1 to 12 do
if month = (2|4|6|9|11) then next
else if julian(month,1,year) % 7 = 4 then
put(L,sprintf("%d-%d-1",year,month))
return L
end
procedure Bonus(start,finish,fwe)
every insert(Y := set(), start to finish)
every insert(F := set(), integer(!fwe ? tab(find("-"))))
return sort(Y--F)
end

View file

@ -0,0 +1,102 @@
Calendar is a room.
When play begins:
let happy month count be 0;
let sad year count be 0;
repeat with Y running from Y1900 to Y2100:
if Y is a sad year, increment the sad year count;
repeat with M running through months:
if M of Y is a happy month:
say "[M] [year number of Y].";
increment the happy month count;
say "Found [happy month count] month[s] with five weekends and [sad year count] year[s] with no such months.";
end the story.
Section - Years
A year is a kind of value. Y1 specifies a year.
To decide which number is year number of (Y - year):
decide on Y / Y1.
To decide if (N - number) is divisible by (M - number):
decide on whether or not the remainder after dividing N by M is zero.
Definition: a year (called Y) is a leap year:
let YN be the year number of Y;
if YN is divisible by 400, yes;
if YN is divisible by 100, no;
if YN is divisible by 4, yes;
no.
Section - Months
A month is a kind of value. The months are defined by the Table of Months.
Table of Months
month month number
January 1
February 2
March 3
April 4
May 5
June 6
July 7
August 8
September 9
October 10
November 11
December 12
A month has a number called length. The length of a month is usually 31.
September, April, June, and November have length 30. February has length 28.
To decide which number is number of days in (M - month) of (Y - year):
let L be the length of M;
if M is February and Y is a leap year, decide on L + 1;
otherwise decide on L.
Section - Weekdays
A weekday is a kind of value. The weekdays are defined by the Table of Weekdays.
Table of Weekdays
weekday weekday number
Saturday 0
Sunday 1
Monday 2
Tuesday 3
Wednesday 4
Thursday 5
Friday 6
To decide which weekday is weekday of the/-- (N - number) of (M - month) of (Y - year):
let MN be the month number of M;
let YN be the year number of Y;
if MN is less than 3:
increase MN by 12;
decrease YN by 1;
let h be given by Zeller's Congruence;
let WDN be the remainder after dividing h by 7;
decide on the weekday corresponding to a weekday number of WDN in the Table of Weekdays.
Equation - Zeller's Congruence
h = N + ((MN + 1)*26)/10 + YN + YN/4 + 6*(YN/100) + YN/400
where h is a number, N is a number, MN is a number, and YN is a number.
To decide which number is number of (W - weekday) days in (M - month) of (Y - year):
let count be 0;
repeat with N running from 1 to the number of days in M of Y:
if W is the weekday of the N of M of Y, increment count;
decide on count.
Section - Happy Months and Sad Years
To decide if (M - month) of (Y - year) is a happy month:
if the number of days in M of Y is 31 and the weekday of the 1st of M of Y is Friday, decide yes;
decide no.
To decide if (Y - year) is a sad year:
repeat with M running through months:
if M of Y is a happy month, decide no;
decide yes.

View file

@ -0,0 +1,7 @@
require 'types/datetime numeric'
find5wkdMonths=: verb define
years=. range 2{. y
months=. 1 3 5 7 8 10 12
m5w=. (#~ 0 = weekday) >,{years;months;31 NB. 5 full weekends iff 31st is Sunday(0)
>'MMM YYYY' fmtDate toDayNo m5w
)

View file

@ -0,0 +1,16 @@
# find5wkdMonths 1900 2100 NB. number of months found
201
(5&{. , '...' , _5&{.) find5wkdMonths 1900 2100 NB. First and last 5 months found
Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100
# (range -. {:"1@(_ ". find5wkdMonths)) 1900 2100 NB. number of years without 5 weekend months
29

View file

@ -0,0 +1,33 @@
import java.util.Calendar;
import java.util.GregorianCalendar;
public class FiveFSS {
private static boolean[] years = new boolean[201];
//dreizig tage habt september...
private static int[] month31 = {Calendar.JANUARY, Calendar.MARCH, Calendar.MAY,
Calendar.JULY, Calendar.AUGUST, Calendar.OCTOBER, Calendar.DECEMBER};
public static void main(String[] args) {
StringBuilder months = new StringBuilder();
int numMonths = 0;
for (int year = 1900; year <= 2100; year++) {
for (int month : month31) {
Calendar date = new GregorianCalendar(year, month, 1);
if (date.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
years[year - 1900] = true;
numMonths++;
//months are 0-indexed in Calendar
months.append((date.get(Calendar.MONTH) + 1) + "-" + year +"\n");
}
}
}
System.out.println("There are "+numMonths+" months with five weekends from 1900 through 2100:");
System.out.println(months);
System.out.println("Years with no five-weekend months:");
for (int year = 1900; year <= 2100; year++) {
if(!years[year - 1900]){
System.out.println(year);
}
}
}
}

View file

@ -0,0 +1,45 @@
function startsOnFriday(month, year)
{
// 0 is Sunday, 1 is Monday, ... 5 is Friday, 6 is Saturday
return new Date(year, month, 1).getDay() === 5;
}
function has31Days(month, year)
{
return new Date(year, month, 31).getDate() === 31;
}
function checkMonths(year)
{
var month, count = 0;
for (month = 0; month < 12; month += 1)
{
if (startsOnFriday(month, year) && has31Days(month, year))
{
count += 1;
document.write(year + ' ' + month + '<br>');
}
}
return count;
}
function fiveWeekends()
{
var
startYear = 1900,
endYear = 2100,
year,
monthTotal = 0,
yearsWithoutFiveWeekends = [],
total = 0;
for (year = startYear; year <= endYear; year += 1)
{
monthTotal = checkMonths(year);
total += monthTotal;
// extra credit
if (monthTotal === 0)
yearsWithoutFiveWeekends.push(year);
}
document.write('Total number of months: ' + total + '<br>');
document.write('<br>');
document.write(yearsWithoutFiveWeekends + '<br>');
document.write('Years with no five-weekend months: ' + yearsWithoutFiveWeekends.length + '<br>');
}
fiveWeekends();

View file

@ -0,0 +1,37 @@
FIVE
;List and count the months between 1/1900 and 12/2100 that have 5 full weekends
;Extra credit - list and count years with no months with five full weekends
;Using the test that the 31st of a month is on a Sunday
;Uses the VA's public domain routine %DTC (Part of the Kernel) named here DIDTC
NEW YEAR,MONTH,X,Y,CNTMON,NOT,NOTLIST
; YEAR is the year we're testing
; MONTH is the month we're testing
; X is the date in "internal" format, as an input to DOW^DIDTC
; Y is the day of the week (0=Sunday, 1=Monday...) output from DOW^DIDTC
; CNTMON is a count of the months that have 5 full weekends
; NOT is a flag if there were no months with 5 full weekends yet that year
; NOTLIST is a list of years that do not have any months with 5 full weekends
SET CNTMON=0,NOTLIST=""
WRITE !!,"The following months have five full weekends:"
FOR YEAR=200:1:400 DO ;years since 12/31/1700 epoch
. SET NOT=0
. FOR MONTH="01","03","05","07","08","10","12" DO
. . SET X=YEAR_MONTH_"31"
. . DO DOW^DIDTC
. . IF (Y=0) DO
. . . SET NOT=NOT+1,CNTMON=CNTMON+1
. . . WRITE !,MONTH_"-"_(YEAR+1700)
. SET:(NOT=0) NOTLIST=NOTLIST_$SELECT($LENGTH(NOTLIST)>1:",",1:"")_(YEAR+1700)
WRITE !,"For a total of "_CNTMON_" months."
WRITE !!,"There are "_$LENGTH(NOTLIST,",")_" years with no five full weekends in any month."
WRITE !,"They are: "_NOTLIST
KILL YEAR,MONTH,X,Y,CNTMON,NOT,NOTLIST
QUIT
F ;Same logic as the main entry point, shortened format
N R,M,X,Y,C,N,L S C=0,L=""
W !!,"The following months have five full weekends:"
F R=200:1:400 D
. S N=0 F M="01","03","05","07","08","10","12" S X=R_M_"31" D DOW^DIDTC I 'Y S N=N+1,C=C+1 W !,M_"-"_(R+1700)
. S:'N L=L_$S($L(L):",",1:"")_(R+1700)
W !,"For a total of "_C_" months.",!!,"There are "_$L(L,",")_" years with no five full weekends in any month.",!,"They are: "_L
Q

View file

@ -0,0 +1,8 @@
years = {1900, 2100}; months = {1 ,3 ,5 ,7 ,8 ,10 ,12};
result = Select[Tuples[{Range@@years, months}], (DateString[# ~ Join ~ 1, "DayNameShort"] == "Fri")&];
Print[result // Length," months with 5 weekends" ];
Print["First months: ", DateString[#,{"MonthName"," ","Year"}]& /@ result[[1 ;; 5]]];
Print["Last months: " , DateString[#,{"MonthName"," ","Year"}]& /@ result[[-5 ;; All]]];
Print[# // Length, " years without 5 weekend months:\n", #] &@
Complement[Range @@ years, Part[Transpose@result, 1]];

View file

@ -0,0 +1,17 @@
left(a, n) := makelist(a[i], i, 1, n)$
right(a, n) := block([m: length(a)], makelist(a[i], i, m - n + 1, m))$
a: [ ]$
for year from 1900 thru 2100 do
for month in [1, 3, 5, 7, 8, 10, 12] do
if weekday(year, month, 1) = 'friday then
a: endcons([year, month], a)$
length(a);
201
left(a, 5);
[[1901,3],[1902,8],[1903,5],[1904,1],[1904,7]]
right(a, 5);
[[2097,3],[2098,8],[2099,5],[2100,1],[2100,10]]

View file

@ -0,0 +1,34 @@
#!/usr/bin/perl -w
use DateTime ;
my @happymonths ;
my @workhardyears ;
my @longmonths = ( 1 , 3 , 5 , 7 , 8 , 10 , 12 ) ;
my @years = 1900..2100 ;
foreach my $year ( @years ) {
my $countmonths = 0 ;
foreach my $month ( @longmonths ) {
my $dt = DateTime->new( year => $year ,
month => $month ,
day => 1 ) ;
if ( $dt->day_of_week == 5 ) {
$countmonths++ ;
my $yearfound = $dt->year ;
my $monthfound = $dt->month_name ;
push ( @happymonths , "$yearfound $monthfound" ) ;
}
}
if ( $countmonths == 0 ) {
push ( @workhardyears, $year ) ;
}
}
print "There are " . @happymonths . " months with 5 full weekends!\n" ;
print "The first 5 and the last 5 of them are:\n" ;
foreach my $i ( 0..4 ) {
print "$happymonths[ $i ]\n" ;
}
foreach my $i ( -5..-1 ) {
print "$happymonths[ $i ]\n" ;
}
print "No long weekends in the following " . @workhardyears . " years:\n" ;
map { print "$_\n" } @workhardyears ;

View file

@ -0,0 +1,17 @@
(setq Lst
(make
(for Y (range 1900 2100)
(for M (range 1 12)
(and
(date Y M 31)
(= "Friday" (day (date Y M 1)))
(link (list (get *Mon M) Y)) ) ) ) ) )
(prinl "There are " (length Lst) " months with five weekends:")
(mapc println (head 5 Lst))
(prinl "...")
(mapc println (tail 5 Lst))
(prinl)
(setq Lst (diff (range 1900 2100) (uniq (mapcar cadr Lst))))
(prinl "There are " (length Lst) " years with no five-weekend months:")
(println Lst)

View file

@ -0,0 +1,34 @@
from datetime import timedelta, date
DAY = timedelta(days=1)
START, STOP = date(1900, 1, 1), date(2101, 1, 1)
WEEKEND = {6, 5, 4} # Sunday is day 6
FMT = '%Y %m(%B)'
def fiveweekendspermonth(start=START, stop=STOP):
'Compute months with five weekends between dates'
when = start
lastmonth = weekenddays = 0
fiveweekends = []
while when < stop:
year, mon, _mday, _h, _m, _s, wday, _yday, _isdst = when.timetuple()
if mon != lastmonth:
if weekenddays >= 15:
fiveweekends.append(when - DAY)
weekenddays = 0
lastmonth = mon
if wday in WEEKEND:
weekenddays += 1
when += DAY
return fiveweekends
dates = fiveweekendspermonth()
indent = ' '
print('There are %s months of which the first and last five are:' % len(dates))
print(indent +('\n'+indent).join(d.strftime(FMT) for d in dates[:5]))
print(indent +'...')
print(indent +('\n'+indent).join(d.strftime(FMT) for d in dates[-5:]))
print('\nThere are %i years in the range that do not have months with five weekends'
% len(set(range(START.year, STOP.year)) - {d.year for d in dates}))

View file

@ -0,0 +1,10 @@
LONGMONTHS = (1, 3, 5, 7, 8, 10, 12) # Jan Mar May Jul Aug Oct Dec
def fiveweekendspermonth2(start=START, stop=STOP):
return [date(yr, month, 31)
for yr in range(START.year, STOP.year)
for month in LONGMONTHS
if date(yr, month, 31).timetuple()[6] == 6 # Sunday
]
dates2 = fiveweekendspermonth2()
assert dates2 == dates

View file

@ -0,0 +1,41 @@
/*REXX program finds months with 5 weekends in them (given a date range)*/
month. =31 /*month days; Feb. is done later.*/
month.4=30; month.6=30; month.9=30; month.11=30 /*30-day months*/
parse arg yStart yStop . /*get the "start" & "stop" years.*/
if yStart=='' then yStart=1900 /*if not specified, use default. */
if yStop =='' then yStop =2100 /* " " " " " */
years=yStop-yStart+1 /*calculate the # of yrs in range*/
haps=0 /*num of five weekends happenings*/
yr5.=0 /*if a year has any five-weekends*/
do y=yStart to yStop /*process the years specified. */
do m=1 for 12; wd.=0 /*each month, each yr*/
if m==2 then month.2=28+leapyear(y) /*handle #days in Feb*/
do d=1 for month.m; dat_=y"-"right(m,2,0)'-'right(d,2,0)
?=left(date('W', dat_, "I"), 2); upper ?
wd.?=wd.?+1 /*? is 1st 2 chars of weekday*/
end /*d*/ /*WD.su=# of Sundays in month*/
if wd.su\==5 | wd.fr\==5 | wd.sa\==5 then iterate /*5 W.E.s?*/
haps=haps+1 /*bump ctr*/
say 'There are five weekends in' y date('M', dat_, "I")
yr5.y=1 /*indicate the year has 5WEs.*/
end /*m*/
end /*y*/
say
say 'There were ' haps " occurrence"s(haps),
'of five-weekend months in year's(years) yStart''yStop; say
no5s=0
do y=yStart to yStop; if yr5.y then iterate /*skip if OK*/
no5s=no5s+1
say 'Year ' y " doesn't have any five-weekend months."
end /*y*/
say
say "There are " no5s ' year's(no5s),
"that haven't any five─weekend months in year"s(years) yStart''yStop
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────LEAPYEAR subroutine─────────────────*/
leapyear: procedure; parse arg y /*year could be: Y, YY, YYY, YYYY*/
if length(y)==2 then y=left(right(date(),4),2)y /*adjust for YY year.*/
if y//4\==0 then return 0 /* not ÷ by 4? Not a leap year.*/
return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */
/*──────────────────────────────────S subroutine────────────────────────*/
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*plural*/

View file

@ -0,0 +1,46 @@
/*REXX program finds months with 5 weekends in them (given a date range)*/
month. =31 /*month days; Feb. is done later.*/
month.4=30; month.6=30; month.9=30; month.11=30 /*30-day months*/
@months='January February March April May June July August September October November December'
parse arg yStart yStop . /*get the "start" & "stop" years.*/
if yStart=='' then yStart=1900 /*if not specified, use default. */
if yStop =='' then yStop =2100 /* " " " " " */
years=yStop-yStart+1 /*calculate the # of yrs in range*/
haps=0 /*num of five weekends happenings*/
yr5.=0 /*if a year has any five-weekends*/
do y=yStart to yStop /*process the years specified. */
do m=1 for 12; wd.=0 /*process each month in each year*/
if m==2 then month.2=28+leapyear(y) /*handle #days in Feb.*/
do d=1 for month.m
?=dow(m,d,y) /*get day-of-week for mm/dd/yyyy.*/
wd.?=wd.?+1 /*?: 1=Sun, 2=Mon, ∙∙∙ 7=Sat */
end /*d*/
if wd.1\==5 | wd.6\==5 | wd.7\==5 then iterate /*5 WEs ? */
haps=haps+1 /*bump ctr*/
say 'There are five weekends in' y word(@months,m)
yr5.y=1 /*indicate this year has 5 WEs. */
end /*m*/
end /*y*/
say
say 'There were ' haps " occurrence"s(haps),
'of five-weekend months in year's(years) yStart''yStop; say
no5s=0
do y=yStart to yStop; if yr5.y then iterate /*skip if OK*/
no5s=no5s+1
say 'Year ' y " doesn't have any five-weekend months."
end /*y*/
say
say "There are " no5s ' year's(no5s),
"that haven't any five─weekend months in year"s(years) yStart''yStop
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────DOW─────────────────────────────────*/
dow: procedure; parse arg m,d,y; if m<3 then do; m=m+12; y=y-1; end
yL=left(y,2); yr=right(y,2); w=(d+(m+1)*26%10+yr+yr%4+yL%4+5*yL) // 7
if w==0 then w=7; return w /*Sunday=1, Monday=2, ... Saturday=7*/
/*──────────────────────────────────LEAPYEAR subroutine─────────────────*/
leapyear: procedure; parse arg y /*year could be: Y, YY, YYY, YYYY*/
if length(y)==2 then y=left(right(date(),4),2)y /*adjust for YY year.*/
if y//4\==0 then return 0 /* not ÷ by 4? Not a leap year.*/
return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */
/*──────────────────────────────────S subroutine────────────────────────*/
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*plural*/

View file

@ -0,0 +1,55 @@
/* REXX ***************************************************************
* Short(er) solution focussed at the task's description
* Only 7 months can have 5 full weekends
* and it's enough to test if the 1st day of the month is a Friday
* 30.08.2012 Walter Pachl
**********************************************************************/
Numeric digits 20
nr5fwe=0
years_without_5fwe=0
mnl='Jan Mar May Jul Aug Oct Dec'
ml='1 3 5 7 8 10 12'
Do j=1900 to 2100
year_has_5fwe=0
Do mi=1 To words(ml)
m=word(ml,mi)
jd=greg2jul(j m 1)
IF jd//7=4 Then Do /* 1st m j is a Friday */
nr5fwe=nr5fwe+1
year_has_5fwe=1
If j<=1905 | 2095<=j Then
Say word(mnl,mi) j 'has 5 full weekends'
End
End
If j=1905 Then Say '...'
if year_has_5fwe=0 Then years_without_5fwe=years_without_5fwe+1
End
Say ' '
Say nr5fwe 'occurrences of 5 full weekends in a month'
Say years_without_5fwe 'years without 5 full weekends'
exit
greg2jul: Procedure
/***********************************************************************
* Converts a Gregorian date to the corresponding Julian day number
* 19891101 Walter Pachl REXXified algorithm published in CACM
* (Fliegel & vanFlandern, CACM Vol.11 No.10 October 1968)
* 19891125 PA copy leapyear test into this to avoid the dependency
***********************************************************************/
numeric digits 12
Parse Arg yy mm d
If mm<1 | 12<mm Then Call err 'month ('mm') not within 1 to 12'
mdl='31' (28+leapyear(yy)) '31 30 31 30 31 31 30 31 30 31'
md=word(mdl,mm)
If d<1 | md<d Then Call err 'day ('d') not within 1 to' md
/***********************************************************************
* The published formula:
* res=d-32075+1461*(yy+4800+(mm-14)%12)%4+,
* 367*(mm-2-((mm-14)%12)*12)%12-3*((yy+4900+(mm-14)%12)%100)%4
***********************************************************************/
mma=(mm-14)%12
yya=yy+4800+mma
result=d-32075+1461*yya%4+367*(mm-2-mma*12)%12-3*((yya+100)%100)%4
Return result /* return the result */
leapyear: Return ( (arg(1)//4=0) & (arg(1)//100<>0) ) | (arg(1)//400=0)

View file

@ -0,0 +1,21 @@
require 'date'
# if the last day of the month falls on a Sunday and the month has 31 days,
# this is the only case where the month has 5 weekends.
start = Date.parse("1900-01-01")
stop = Date.parse("2100-12-31")
dates = (start..stop).find_all do |day|
day.mday == 31 and day.wday == 0 # Ruby 1.9: and day.sunday?
end
puts "There are #{dates.size} months with 5 weekends from 1900 to 2100:"
puts dates[0, 5].map { |d| d.strftime("%b %Y") }.join("\n")
puts "..."
puts dates[-5, 5].map { |d| d.strftime("%b %Y") }.join("\n")
years_with_5w = dates.map(&:year)
years = (1900..2100).to_a - years_with_5w
puts "There are #{years.size} years without months with 5 weekends:"
puts years.join(", ")

View file

@ -0,0 +1,22 @@
package require Tcl 8.5
set months {}
set years {}
for {set year 1900} {$year <= 2100} {incr year} {
set count [llength $months]
foreach month {Jan Mar May Jul Aug Oct Dec} {
set date [clock scan "$month/01/$year" -format "%b/%d/%Y" -locale en_US]
if {[clock format $date -format %u] == 5} {
# Month with 31 days that starts on a Friday => has 5 weekends
lappend months "$month $year"
}
}
if {$count == [llength $months]} {
# No change to number of months; year must've been without
lappend years $year
}
}
puts "There are [llength $months] months with five weekends"
puts [join [list {*}[lrange $months 0 4] ... {*}[lrange $months end-4 end]] \n]
puts "There are [llength $years] years without any five-weekend months"
puts [join $years ","]