# Five weekends

Five weekends
You are encouraged to solve this task according to the task description, using any language you may know.

The month of October in 2010 has five Fridays, five Saturdays, and five Sundays.

1. Write a program to show all months that have this same characteristic of five full weekends from the year 1900 through 2100 (Gregorian calendar).
2. Show the number of months with this property (there should be 201).
3. 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).

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; </lang> Sample output:

``` 1901 3
1902 8
1903 5
1904 1
1904 7
1905 12
1907 3
1908 5
1909 1
1909 10
1910 7
1911 12
1912 3
1913 8
1914 5
1915 1
1915 10
1916 12
1918 3
1919 8
1920 10
1921 7
1922 12
1924 8
1925 5
1926 1
1926 10
1927 7
1929 3
1930 8
1931 5
1932 1
1932 7
1933 12
1935 3
1936 5
1937 1
1937 10
1938 7
1939 12
1940 3
1941 8
1942 5
1943 1
1943 10
1944 12
1946 3
1947 8
1948 10
1949 7
1950 12
1952 8
1953 5
1954 1
1954 10
1955 7
1957 3
1958 8
1959 5
1960 1
1960 7
1961 12
1963 3
1964 5
1965 1
1965 10
1966 7
1967 12
1968 3
1969 8
1970 5
1971 1
1971 10
1972 12
1974 3
1975 8
1976 10
1977 7
1978 12
1980 8
1981 5
1982 1
1982 10
1983 7
1985 3
1986 8
1987 5
1988 1
1988 7
1989 12
1991 3
1992 5
1993 1
1993 10
1994 7
1995 12
1996 3
1997 8
1998 5
1999 1
1999 10
2000 12
2002 3
2003 8
2004 10
2005 7
2006 12
2008 8
2009 5
2010 1
2010 10
2011 7
2013 3
2014 8
2015 5
2016 1
2016 7
2017 12
2019 3
2020 5
2021 1
2021 10
2022 7
2023 12
2024 3
2025 8
2026 5
2027 1
2027 10
2028 12
2030 3
2031 8
2032 10
2033 7
2034 12
2036 8
2037 5
2038 1
2038 10
2039 7
2041 3
2042 8
2043 5
2044 1
2044 7
2045 12
2047 3
2048 5
2049 1
2049 10
2050 7
2051 12
2052 3
2053 8
2054 5
2055 1
2055 10
2056 12
2058 3
2059 8
2060 10
2061 7
2062 12
2064 8
2065 5
2066 1
2066 10
2067 7
2069 3
2070 8
2071 5
2072 1
2072 7
2073 12
2075 3
2076 5
2077 1
2077 10
2078 7
2079 12
2080 3
2081 8
2082 5
2083 1
2083 10
2084 12
2086 3
2087 8
2088 10
2089 7
2090 12
2092 8
2093 5
2094 1
2094 10
2095 7
2097 3
2098 8
2099 5
2100 1
2100 10
Number of months: 201
```

## AppleScript

<lang AppleScript>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
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</lang>

Output (can always add "display dialog resultText" for GUI output):

```Months with five weekends (201):
1901-March, 1902-August, 1903-May, 1904-January, 1904-July, ...
..., 2097-March, 2098-August, 2099-May, 2100-January, 2100-October

Years with no such months (29):
1900, 1906, 1917, 1923, 1928, 1934, 1945, 1951, 1956, 1962, 1973, 1979
1984, 1990, 2001, 2007, 2012, 2018, 2029, 2035, 2040, 2046, 2057, 2063
2068, 2074, 2085, 2091, 2096```

## AutoHotkey

<lang AutoHotkey>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% )</lang>

## AutoIt

Call the Funktion with \$ret > 1 And \$ret < 3 to determine Returned Array 1 - All found Weekend Dates 2 - Years Without 5 Weekend Months 3 - Year and Month with 5 Weekends <lang AutoIt>

1. include <Date.au3>
2. 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 </lang>

## ALGOL 68

Translation of: Fortran
Note: This specimen retains the original Fortran coding style. diff
Works with: ALGOL 68 version Revision 1 - no extensions to language used.
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny.

<lang algol68>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));

```
1. 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 #</lang> Output:

```Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100
Number of months with five weekends between 1900 and 2100 = 201
Number of years between 1900 and 2100 with no five weekend months = 29
```

## BBC BASIC

<lang bbcbasic> 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%</lang>
```

Output:

```1900: (none)
1901: March
1902: August
1903: May
1904: January       July
1905: December
1906: (none)
...
2093: May
2094: January       October
2095: July
2096: (none)
2097: March
2098: August
2099: May
2100: January       October
Total = 201
```

## C

<lang c>#include <stdio.h>

1. 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;
```

}</lang> Output (note that the C library may not be able to handle all dates; the output may vary across systems):

```Error: 1900 January
Error: 1900 March
Error: 1900 May
Error: 1900 July
Error: 1900 August
Error: 1900 October
Error: 1900 December
Error: 1901 January
Error: 1901 March
Error: 1901 May
Error: 1901 July
Error: 1901 August
Error: 1901 October
Error: 1901 December
1902 August
1903 May
1904 January
1904 July
1905 December
...
2097 March
2098 August
2099 May
2100 January
2100 October
200 total
```

Not your typical method. Requires `ncal`. <lang c>#include <stdio.h>

1. 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;

1. 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; }</lang> output

```1901-03 1902-08 1903-05 1904-01 1904-07 1905-12 1907-03 1908-05 1909-01 1909-10 1910-07 1911-12 1912-03 1913-08 1914-05 1915-01
.
.
.
2093-05 2094-01 2094-10 2095-07 2097-03 2098-08 2099-05 2100-01 2100-10
Total: 201
```

## C++

Library: Boost

<lang cpp>#include <vector>

1. include <boost/date_time/gregorian/gregorian.hpp>
2. include <algorithm>
3. include <iostream>
4. 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 ;
```

}</lang> sample output:

```Between 1900 and 2100 , there are 201 months with 5 complete weekends!
Months with 5 complete weekends are:
1901-Mar
1902-Aug
1903-May
1904-Jan
1904-Jul
1905-Dec
1907-Mar
1908-May
1909-Jan
1909-Oct
1910-Jul
1911-Dec
1912-Mar
1913-Aug
1914-May
1915-Jan
1915-Oct
1916-Dec
1918-Mar
1919-Aug
1920-Oct
1921-Jul
1922-Dec
1924-Aug
1925-May
1926-Jan
1926-Oct
1927-Jul
1929-Mar
1930-Aug
1931-May
1932-Jan
1932-Jul
1933-Dec
1935-Mar
1936-May
1937-Jan
1937-Oct
1938-Jul
1939-Dec
1940-Mar
1941-Aug
1942-May
1943-Jan
1943-Oct
1944-Dec
1946-Mar
1947-Aug
1948-Oct
1949-Jul
1950-Dec
1952-Aug
1953-May
1954-Jan
1954-Oct
1955-Jul
1957-Mar
1958-Aug
1959-May
1960-Jan
1960-Jul
1961-Dec
1963-Mar
1964-May
1965-Jan
1965-Oct
1966-Jul
1967-Dec
1968-Mar
1969-Aug
1970-May
1971-Jan
1971-Oct
1972-Dec
1974-Mar
1975-Aug
1976-Oct
1977-Jul
1978-Dec
1980-Aug
1981-May
1982-Jan
1982-Oct
1983-Jul
1985-Mar
1986-Aug
1987-May
1988-Jan
1988-Jul
1989-Dec
1991-Mar
1992-May
1993-Jan
1993-Oct
1994-Jul
1995-Dec
1996-Mar
1997-Aug
1998-May
1999-Jan
1999-Oct
2000-Dec
2002-Mar
2003-Aug
2004-Oct
2005-Jul
2006-Dec
2008-Aug
2009-May
2010-Jan
2010-Oct
2011-Jul
2013-Mar
2014-Aug
2015-May
2016-Jan
2016-Jul
2017-Dec
2019-Mar
2020-May
2021-Jan
2021-Oct
2022-Jul
2023-Dec
2024-Mar
2025-Aug
2026-May
2027-Jan
2027-Oct
2028-Dec
2030-Mar
2031-Aug
2032-Oct
2033-Jul
2034-Dec
2036-Aug
2037-May
2038-Jan
2038-Oct
2039-Jul
2041-Mar
2042-Aug
2043-May
2044-Jan
2044-Jul
2045-Dec
2047-Mar
2048-May
2049-Jan
2049-Oct
2050-Jul
2051-Dec
2052-Mar
2053-Aug
2054-May
2055-Jan
2055-Oct
2056-Dec
2058-Mar
2059-Aug
2060-Oct
2061-Jul
2062-Dec
2064-Aug
2065-May
2066-Jan
2066-Oct
2067-Jul
2069-Mar
2070-Aug
2071-May
2072-Jan
2072-Jul
2073-Dec
2075-Mar
2076-May
2077-Jan
2077-Oct
2078-Jul
2079-Dec
2080-Mar
2081-Aug
2082-May
2083-Jan
2083-Oct
2084-Dec
2086-Mar
2087-Aug
2088-Oct
2089-Jul
2090-Dec
2092-Aug
2093-May
2094-Jan
2094-Oct
2095-Jul
2097-Mar
2098-Aug
2099-May
2100-Jan
2100-Oct
29 years had no months with 5 complete weekends!
These are:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096
```

## C#

<lang csharp>using System;

namespace _5_Weekends {

```   class Program
{
const int FIRST_YEAR = 1900;
const int LAST_YEAR = 2100;
static int[] _31_MONTHS = { 1, 3, 5, 7, 8, 10, 12 };
```
```       static void Main(string[] args)
{
int totalNum = 0;
int totalNo5Weekends = 0;
```
```           for (int year = FIRST_YEAR; year <= LAST_YEAR; year++)
{
bool has5Weekends = false;
```
```               foreach (int month in _31_MONTHS)
{
DateTime firstDay = new DateTime(year, month, 1);
if (firstDay.DayOfWeek == DayOfWeek.Friday)
{
totalNum++;
has5Weekends = true;
Console.WriteLine(firstDay.ToString("yyyy - MMMM"));
}
}
```
```               if (!has5Weekends) totalNo5Weekends++;
}
Console.WriteLine("Total 5-weekend months between {0} and {1}: {2}", FIRST_YEAR, LAST_YEAR, totalNum);
Console.WriteLine("Total number of years with no 5-weekend months {0}", totalNo5Weekends);
}
}
```

}</lang> Output

```1901 - March
1902 - August
1903 - May
1904 - January
1904 - July
1905 - December
...
2095 - July
2097 - March
2098 - August
2099 - May
2100 - January
2100 - October
Total 5-weekend months between 1900 and 2100: 201
Total number of years with no 5-weekend months 29
```

## Clojure

<lang Clojure>(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: " ,))</lang>
```

## D

<lang d>import std.stdio, std.datetime, std.algorithm, std.range;

Date[] m5w(in Date start, in Date end) pure /*nothrow*/ {

```   typeof(return) res;
for (Date when = Date(start.year, start.month, 1);
when < end;
// 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);
```

}</lang>

Output:
```There are 201 months of which the first and last five are:
1901-Mar
1902-Aug
1903-May
1904-Jan
1904-Jul
2097-Mar
2098-Aug
2099-May
2100-Jan
2100-Oct

There are 29 years in the range that do not have months with five weekends.```

### Simpler Version

<lang d>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);
```

}</lang>

Output:
```Total 5-weekend months between 1900 and 2100: 201
mar 1901
aug 1902
may 1903
jan 1904
jul 1904
...
mar 2097
aug 2098
may 2099
jan 2100
oct 2100

Total number of years with no 5-weekend months: 29```

## Delphi

<lang delphi>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.</lang>

## Erlang

Two examples, both based on first building a nested list-of-lists like [Year1, Year2, ..., YearN], where each year is a sublist of year and month tuples, like [{YearN, 1}, {YearN, 2}, ..., {YearN, 12}].
First, a pretty compact example intended for use with escript: <lang erlang>

1. !/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.
```

</lang> Second, a more verbose Erlang module: <lang erlang> -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].
```

</lang> Output

```There are 201 months with five full weekends.
Showing top and bottom 5:
1901-3
1902-8
1903-5
1904-1
1904-7
2097-3
2098-8
2099-5
2100-1
2100-10
The following 29 years do NOT have any five-weekend months:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096
```

## Euphoria

<lang Euphoria> --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 </lang> Output

```Number of months with five full weekends from 1900 to 2100 = 201
First five and last five years, months
{1901,3}
{1902,8}
{1903,5}
{1904,1}
{1904,7}
{2097,3}
{2098,8}
{2099,5}
{2100,1}
{2100,10}
Number of years that have no months with five full weekends = 29
```

## Fortran

Works with: Fortran version 95 and later

Using Zeller's congruence <lang fortran>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</lang> Output

```Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100
Number of months with five weekends between 1900 and 2100 = 201
Number of years between 1900 and 2100 with no five weekend months = 29```

## GAP

<lang gap># return a list of two lists :

1. first is the list of months with five weekends between years y1 and y2 (included)
2. 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 := [ ];
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]);
fi;
od;
if Length(yL) = 0 then
else
Append(L, yL);
fi;
od;
```

end;

r := FiveWeekends(1900, 2100);; n := Length(r[1]);

1. 201

Length(r[2]);

1. 29

r[1]{[1 .. 5]};

1. [ "Mar-1901", "Aug-1902", "May-1903", "Jan-1904", "Jul-1904" ]

r[1]{[n-4 .. n]};

1. [ "Mar-2097", "Aug-2098", "May-2099", "Jan-2100", "Oct-2100" ]</lang>

## Go

Using second algorithm suggestion: <lang go>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
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")
```

}</lang> Output:

```Months with five weekends:
1901 March
1902 August
1903 May
1904 January
1904 July
...
2097 March
2098 August
2099 May
2100 January
2100 October
201 total

First five dates of weekends:
Friday, March 1, 1901
Friday, March 8, 1901
Friday, March 15, 1901
Friday, March 22, 1901
Friday, March 29, 1901
Last five dates of weekends:
Friday, October 1, 2100
Friday, October 8, 2100
Friday, October 15, 2100
Friday, October 22, 2100
Friday, October 29, 2100

Years with no months with five weekends:
1900
1906
1917
1923
1928
....
2068
2074
2085
2091
2096
29 total
```

Not using any helper libraries, this code profits from Haskell's lazy evaluation. Knowing that the first day of 1900 was a Monday, we make an infinit list of days and split it in years and months. To do this, we take and drop days from the head of the list of days.

year 1900 = [Monday, Tuesday, Wednesday...] (365 items) year 1904 = [Friday, Saturday, Sunday...] (366 items -- leap year)

and also:

year 1900 = [(January, [Monday, Tuesday..]), (February, [Thursday, Friday..]), ...]

Now it is easy to get all months with 31 days that start on Friday. <lang Haskell>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
-- 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:"

```

formatMonth :: (Year, [Month]) -> String formatMonth (y, m) = show y ++ ": " ++ intercalate ", " [ show x | x <- m ]</lang> Output:

```There are 201 months with 5 weekends between 1900 and 2100.

The first ones are:
1901: March
1902: August
1903: May
1904: January, July
1905: December

The last ones are:
2095: July
2097: March
2098: August
2099: May
2100: January, October

29 years don't have at least one five-weekended month

Those are:
1900, 1906, 1917, 1923, 1928, 1934, 1945, 1951, 1956, 1962, 1973, 1979, 1984, 1990, 2001, 2007, 2012, 2018, 2029, 2035, 2040, 2046, 2057, 2063, 2068, 2074, 2085, 2091, 2096
```

## Inform 7

Inform 7 has no built-in date functions, so this solution implements date types and a day-of-week function.

<lang inform7>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.</lang>

Output:

```March 1901.
August 1902.
May 1903.
January 1904.
July 1904.
...
March 2097.
August 2098.
May 2099.
January 2100.
October 2100.
Found 201 months with five weekends and 29 years with no such months.```

## Icon and Unicon

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</lang>

Output:
```There are 201 months from 1900 to 2100 with five full weekends.
The first and last five such months are:
1901-3-1
1902-8-1
1903-5-1
1904-1-1
1904-7-1
...
2098-8-1
2099-5-1
2100-1-1
2100-10-1
There are 29 years without such months as follows:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096```

## J

<lang j>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
```

)</lang> Usage: <lang j> # 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</lang>

## Java

In Java 1.5+ you can add `import static java.util.Calendar.*;` to the list of imports and remove all other occurrences of `Calendar.` from the rest of the code (e.g. `Calendar.FRIDAY` would simply become `FRIDAY`). It's more portable (and probably more clear) to leave the `Calendar.`'s in. <lang java>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);
}
}
}
```

}</lang> Output (middle results cut out):

``` There are 201 months with five weekends from 1900 through 2100:
3-1901
8-1902
5-1903
1-1904
7-1904
12-1905
3-1907
5-1908
1-1909
10-1909
7-1910
...
12-2090
8-2092
5-2093
1-2094
10-2094
7-2095
3-2097
8-2098
5-2099
1-2100
10-2100

Years with no five-weekend months:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096```

## JavaScript

<lang javascript>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 + '');
}
}
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 + '');
document.write('');
document.write(yearsWithoutFiveWeekends + '');
document.write('Years with no five-weekend months: ' + yearsWithoutFiveWeekends.length + '');
```

} fiveWeekends();</lang>

Sample output:

```1901 2
1902 7
1903 4
1904 0
1904 6
...
2097 2
2098 7
2099 4
2100 0
2100 9
Total number of months: 201

1900,1906,1917,1923,1928,1934,1945,1951,1956,1962,1973,1979,1984,1990,2001,2007,2012,2018,2029,2035,2040,2046,2057,2063,2068,2074,2085,2091,2096
Years with no five-weekend months: 29```

### Alternative Version

This is an alternative solution that uses the offset between the first day of every month, generating the same solution but without relying on the Date object. <lang javascript>var Months = [

``` 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'
```

];

var leap = 0,

``` // Relative offsets between first day of each month
offset = [3,0,3,2,3,2,3,3,2,3,2,3],
```
``` // Months that contain 31 days
longMonths = [1,3,5,7,8,10,12],
```
``` startYear = 1900,
year = startYear,
endYear = 2100,
```
``` // Jan 1, 1900 starts on a Monday
day = 1,
```
``` totalPerYear = 0,
total = 0,
without = 0;
```

for (; year < endYear + 1; year++) {

``` leap = totalPerYear = 0;
```
``` if (year % 4 === 0) {
if (year % 100 === 0) {
if (year % 400 === 0) {
leap = 1;
}
} else {
leap = 1;
}
}
```
``` for (var i = 0; i < offset.length; i++) {
for (var j = 0; day === 5 && j < longMonths.length; j++) {
if (i + 1 === longMonths[j]) {
console.log(year + '-' + Months[i]);
totalPerYear++;
total++;
break;
}
}
```
```   // February -- if leap year, then +1 day
if (i == 1) {
day = (day + leap) % 7;
} else {
day = (day + offset[i]) % 7;
}
}
```
``` if (totalPerYear === 0) {
without++;
}
```

}

console.log('Number of months that have five full weekends from 1900 to 2100: ' + total); console.log('Number of years without any five full weekend months: ' + without);</lang> Output:

```1901-Mar
1902-Aug
1903-May
1904-Jan
1904-Jul
...
2097-Mar
2098-Aug
2099-May
2100-Jan
2100-Oct
Number of months that have five full weekends from 1900 to 2100: 201
Number of years without any five full weekend months: 29```

## k

<lang k> cal_j:(_jd[19000101]+!(-/_jd 21010101 19000101)) / enumerate the calendar is_we:(cal_j!7) _lin 4 5 6 / identify friday saturdays and sundays m:__dj[cal_j]%100 / label the months mi:&15=+/'is_we[=m] / group by month and sum the weekend days `0:,"There are ",(\$#mi)," months with five weekends" m5:(?m)[mi] `0:\$5#m5 `0:,"..." `0:\$-5#m5 y:1900+!201 / enumerate the years in the range y5:?_ m5%100 / label the years of the months yn5:y@&~y _lin y5 / find any years not in the 5 weekend month list `0:,"There are ",(\$#yn5)," years without any five-weekend months" `0:,1_,/",",/:\$yn5</lang> Output:

```There are 201 months with five weekends
190103
190208
190305
190401
190407
...
209703
209808
209905
210001
210010
There are 29 years without any five-weekend months
1900,1906,1917,1923,1928,1934,1945,1951,1956,1962,1973,1979,1984,1990,2001,2007,2012,2018,2029,2035,2040,2046,2057,2063,2068,2074,2085,2091,2096```

## Mathematica

<lang Mathematica>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"}]& /@ result1 ;; 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]];</lang>
```

output:

```201 months with 5 weekends
First months: {March 1901, August 1902, May 1903, January 1904, July 1904}
Last months:  {March 2097, August 2098, May 2099, January 2100, October 2100}
29 years without 5 weekend months
{1900, 1906, 1917, 1923, 1928, 1934, 1945, 1951, 1956, 1962, 1973, 1979,
1984, 1990, 2001, 2007, 2012, 2018, 2029, 2035, 2040, 2046, 2057, 2063,
2068, 2074, 2085, 2091, 2096}```

## MATLAB / Octave

<lang Matlab>longmonth = [1 3 5 7 8 10 12];

i = 1;

for y = 1900:2100

```   for m = 1:numel(longmonth)
[num,name] = weekday(datenum(y,longmonth(m),1));
if num == 6
x(i,:) = datestr(datenum(y,longmonth(m),1),'mmm yyyy'); %#ok<SAGROW>
i = i+1;
end
end
```

end

fprintf('There are %i months with 5 weekends between 1900 and 2100.\n',length(x))

fprintf('\n The first 5 months are:\n') for j = 1:5

```   fprintf('\t %s \n',x(j,:))
```

end

fprintf('\n The final 5 months are:\n') for j = length(x)-4:length(x)

```   fprintf('\t %s \n',x(j,:))
```

end</lang> Output:

```There are 201 months with 5 weekends between 1900 and 2100.

The first 5 months are:
Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904

The final 5 months are:
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100 ```

## Maxima

<lang maxima>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]]</lang>

## MUMPS

Library: VA Kernel version 22.0

<lang MUMPS> 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</lang>Usage:
```USER>d ^FIVE

The following months have five full weekends:
03-1901
08-1902
05-1903
01-1904
07-1904
12-1905
. . . . . .
01-2094
10-2094
07-2095
03-2097
08-2098
05-2099
01-2100
10-2100
For a total of 201 months.

There are 29 years with no five full weekends in any month.
They are: 1900,1906,1917,1923,1928,1934,1945,1951,1956,1962,1973,1979,1984,1990,2001,2007,2012,2018,2029,2035,2040,2046,2057,2063,2068,2074,2085,2091,2096```

## NetRexx

<lang netrexx> /* NetRexx ************************************************************

• 30.08.2012 Walter Pachl derived from Rexx version 3
• omitting dead code left there
• /

options replace format comments java crossref savelog symbols 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' Loop j=1900 To 2100

``` year_has_5fwe=0
Loop mi=1 To ml.words()
m=ml.word(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 mnl.word(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

method greg2jul(yy,mm,d) public static returns Rexx /***********************************************************************

• 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)
• /
``` numeric digits 12
```

/***********************************************************************

• 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              */</lang>
```

Output: see Rexx version 3

## OCaml

<lang ocaml>open CalendarLib

let list_first_five = function

``` | x1 :: x2 :: x3 :: x4 :: x5 :: _ -> [x1; x2; x3; x4; x5]
| _ -> invalid_arg "list_first_five"
```

let () =

``` let months = ref [] in
for year = 1900 to 2100 do
for month = 1 to 12 do
let we = ref 0 in
let num_days = Date.days_in_month (Date.make_year_month year month) in
for day = 1 to num_days - 2 do
let d0 = Date.day_of_week (Date.make year month day)
and d1 = Date.day_of_week (Date.make year month (day + 1))
and d2 = Date.day_of_week (Date.make year month (day + 2)) in
if (d0, d1, d2) = (Date.Fri, Date.Sat, Date.Sun) then incr we
done;
if !we = 5 then months := (year, month) :: !months
done;
done;
Printf.printf "Number of months with 5 weekends: %d\n" (List.length !months);
print_endline "First and last months between 1900 and 2100:";
let print_month (year, month) = Printf.printf "%d-%02d\n" year month in
List.iter print_month (list_first_five (List.rev !months));
List.iter print_month (List.rev (list_first_five !months));
```
</lang>

Output:

```\$ ocaml unix.cma str.cma -I +calendar calendarLib.cma five_we.ml
Number of months with 5 weekends: 201
First and last months between 1900 and 2100:
1901-03
1902-08
1903-05
1904-01
1904-07
2097-03
2098-08
2099-05
2100-01
2100-10```

## PARI/GP

<lang parigp>fiveWeekends()={ my(day=6); \\ 0 = Friday; this represents Thursday for March 1, 1900. my(ny=[31,30,31,30,31,31,30,31,30,31,31,28],ly=ny,v,s); ly[12]=29; for(year=1900,2100, v=if((year+1)%4,ny,ly); \\ Works for 1600 to 2398 for(month=1,12, if(v[month] == 31 && !day, if(month<11, print(year" "month+2) , print(year+1" 1") ); s++ ); day = (day + v[month])%7 ) ); s };</lang>

See Delphi

## Perl

<lang perl>#!/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 ;</lang> Output:

```There are 201 months with 5 full weekends!
The first 5 and the last 5 of them are:
1901  March
1902  August
1903  May
1904  January
1904  July
2097  March
2098  August
2099  May
2100  January
2100  October
No 5 weekends per month in the following 29 years:
1900
1906
1917
1923
1928
1934
1945
1951
1956
1962
1973
1979
1984
1990
2001
2007
2012
2018
2029
2035
2040
2046
2057
2063
2068
2074
2085
2091
2096
```

## Perl 6

Works with: Rakudo version 2010.11

<lang perl6># A month has 5 weekends iff it has 31 days and starts on Friday.

my @years = 1900 .. 2100; my @ym = @years X 1, 3, 5, 7, 8, 10, 12; # Months with 31 days

my @happy = @ym.map({ Date.new: \$^a, \$^b, 1 }).grep: { .day-of-week == 5 };

say 'Happy month count: ', +@happy; say 'First happy months: ' ~ @happy[^5]; say 'Last happy months: ' ~ @happy[*-5 .. *]; say 'Dreary years count: ', @years - @happy».year.uniq;</lang>

Output:

```Happy month count:  201
First happy months: 1901-03-01 1902-08-01 1903-05-01 1904-01-01 1904-07-01
Last  happy months: 2097-03-01 2098-08-01 2099-05-01 2100-01-01 2100-10-01
Dreary years count: 29```

## PicoLisp

<lang PicoLisp>(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)</lang> Output:

```There are 201 months with five weekends:
(Mar 1901)
(Aug 1902)
(May 1903)
(Jan 1904)
(Jul 1904)
...
(Mar 2097)
(Aug 2098)
(May 2099)
(Jan 2100)
(Oct 2100)

There are 29 years with no five-weekend months:
(1900 1906 1917 1923 1928 1934 1945 1951 1956 1962 1973 1979 1984 1990 2001 2007
2012 2018 2029 2035 2040 2046 2057 2063 2068 2074 2085 2091 2096)```

## Pike

<lang Pike>int(0..1) weekends(object day) {

```   return (<5,6,7>)[day->week_day()];
```

}

int(0..1) has5(object month) {

```   return sizeof(filter(month->days(), weekends))==15;
```

}

object range = Calendar.Year(1900)->distance(Calendar.Year(2101)); array have5 = filter(range->months(), has5);

write("found %d months:\n%{%s\n%}...\n%{%s\n%}",

```      sizeof(have5), have5[..4]->format_nice(), have5[<4..]->format_nice());
```

array rest = range->years() - have5->year(); write("%d years without any 5 weekend month:\n %{%d,%}\n", sizeof(rest), rest->year_no());</lang>

Output:

```found 201 months:
March 1901
August 1902
May 1903
January 1904
July 1904
...
March 2097
August 2098
May 2099
January 2100
October 2100
```
```29 years without any 5 weekend month:
1900,1906,1917,1923,1928,1934,1945,1951,1956,1962,1973,1979,1984,1990,2001,2007,2012,2018,2029,2035,2040,2046,2057,2063,2068,2074,2085,2091,2096,
```

## PL/I

<lang PL/I> weekends: procedure options (main); /* 28/11/2011 */

```  declare tally fixed initial (0);
declare (d, dend, dn) fixed (10);
declare (date_start, date_end) picture '99999999';
declare Leap fixed (1);
```
```  date_start = '01011900';
do date_start = date_start to '01012100';
d        = days(date_start, 'DDMMYYYY');
date_end = date_start + 30110000;
dend     = days(date_end,   'DDMMYYYY');
Leap     = dend-d-364;
do dn = d, d+59+Leap, d+120+Leap, d+181+Leap, d+212+Leap,
d+273+Leap, d+334+Leap;
if weekday(dn) = 6 then
do;
put skip list (daystodate(dn, 'MmmYYYY') || ' has 5 weekends' );
tally = tally + 1;
end;
end;
end;
```
```  put skip list ('Total number of months having 3-day weekends =', tally);
```

end weekends; </lang> OUTPUT:

```Mar1901 has 5 weekends
Aug1902 has 5 weekends
May1903 has 5 weekends
Jan1904 has 5 weekends
Jul1904 has 5 weekends
Dec1905 has 5 weekends
.....
Jan2094 has 5 weekends
Oct2094 has 5 weekends
Jul2095 has 5 weekends
Mar2097 has 5 weekends
Aug2098 has 5 weekends
May2099 has 5 weekends
Jan2100 has 5 weekends
Oct2100 has 5 weekends
Total number of months having 3-day weekends =       201
```

Part 2: Years not having any month of 5 weekends:

```weekends: procedure options (main);
declare tally fixed initial (0);
declare (d, dend, dn) fixed (10);
declare (date_start, date_end) picture '99999999';
declare Leap fixed (1);
declare Long_weekend bit (1);

date_start = '01011900';
do date_start = date_start to '01012100';
d        = days(date_start, 'DDMMYYYY');
date_end = date_start + 30110000;
dend     = days(date_end,   'DDMMYYYY');
Leap     = dend-d-364;
long_weekend = '0'b;
do dn = d, d+59+Leap, d+120+Leap, d+181+Leap, d+212+Leap,
d+273+Leap, d+334+Leap;
if weekday(dn) = 6 then long_weekend = '1'b;
end;
if ^long_weekend then
put skip list (daystodate(dn, 'YYYY') || ' has no month of 5 weekends');
end;

end weekends;
```

OUTPUT:

```1900 has no month of 5 weekends
1906 has no month of 5 weekends
1917 has no month of 5 weekends
1923 has no month of 5 weekends
1928 has no month of 5 weekends
1934 has no month of 5 weekends
1945 has no month of 5 weekends
1951 has no month of 5 weekends
1956 has no month of 5 weekends
1962 has no month of 5 weekends
1973 has no month of 5 weekends
1979 has no month of 5 weekends
1984 has no month of 5 weekends
1990 has no month of 5 weekends
2001 has no month of 5 weekends
2007 has no month of 5 weekends
2012 has no month of 5 weekends
2018 has no month of 5 weekends
2029 has no month of 5 weekends
2035 has no month of 5 weekends
2040 has no month of 5 weekends
2046 has no month of 5 weekends
2057 has no month of 5 weekends
2063 has no month of 5 weekends
2068 has no month of 5 weekends
2074 has no month of 5 weekends
2085 has no month of 5 weekends
2091 has no month of 5 weekends
2096 has no month of 5 weekends
```

## PureBasic

<lang PureBasic>Procedure DateG(year.w, month.b, day)

``` ;Returns the number of days before or after the earliest reference date
;in PureBasic's Date Library (1 Jan 1970) based on an assumed Gregorian calendar calculation
Protected days
days = (year) * 365 + (month - 1) * 31 + day - 1 - 719527 ;DAYS_UNTIL_1970_01_01 = 719527
If month >= 3
days - Int(0.4 * month + 2.3)
Else
year - 1
EndIf
days + Int(year/4) - Int(year/100) + Int(year/400)

ProcedureReturn days
```

EndProcedure

Procedure startsOnFriday(year, month)

``` ;0 is Sunday, 1 is Monday, ... 5 is Friday, 6 is Saturday
Protected referenceDay = DayOfWeek(Date(1970, 1, 1, 0, 0, 0)) ;link to the first day in the PureBasic's date library
Protected resultDay = (((DateG(year, month, 1) + referenceDay) % 7) + 7) % 7
If resultDay = 5
ProcedureReturn #True
EndIf
```

EndProcedure

Procedure has31Days(month)

``` Select month
Case 1, 3, 5, 7 To 8, 10, 12
ProcedureReturn #True
EndSelect
```

EndProcedure

Procedure checkMonths(year)

``` Protected month, count
For month = 1 To 12
If startsOnFriday(year, month) And has31Days(month)
count + 1
PrintN(Str(year) + " " + Str(month))
EndIf
Next
ProcedureReturn count
```

EndProcedure

Procedure fiveWeekends()

``` Protected startYear = 1900, endYear = 2100, year, monthTotal, total
NewList yearsWithoutFiveWeekends()

For year = startYear To endYear
monthTotal = checkMonths(year)
total + monthTotal
;extra credit
If monthTotal = 0
yearsWithoutFiveWeekends() = year
EndIf
Next

PrintN("Total number of months: " + Str(total) + #CRLF\$)
PrintN("Years with no five-weekend months: " + Str(ListSize(yearsWithoutFiveWeekends())) )
```

EndProcedure

If OpenConsole()

``` fiveWeekends()

Print(#CRLF\$ + #CRLF\$ + "Press ENTER to exit"): Input()
CloseConsole()
```

EndIf</lang> Sample output:

```1901 3
1902 8
1903 5
1904 1
1904 7
.
.(output clipped)
.
2097 3
2098 8
2099 5
2100 1
2100 10
Total number of months: 201

Years with no five-weekend months: 29```

## Python

<lang python>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}))</lang>
```

Alternate Algorithm

The condition is equivalent to having a thirty-one day month in which the last day of the month is a Sunday. <lang python>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</lang>

Sample Output

```There are 201 months of which the first and last five are:
1901 03(March)
1902 08(August)
1903 05(May)
1904 01(January)
1904 07(July)
...
2097 03(March)
2098 08(August)
2099 05(May)
2100 01(January)
2100 10(October)

There are 29 years in the range that do not have months with five weekends```

## R

<lang rsplus>ms = as.Date(sapply(c(1, 3, 5, 7, 8, 10, 12),

```   function(month) paste(1900:2100, month, 1, sep = "-")))
```

ms = format(sort(ms[weekdays(ms) == "Friday"]), "%b %Y") message("There are ", length(ms), " months with five weekends.") message("The first five: ", paste(ms[1:5], collapse = ", ")) message("The last five: ", paste(tail(ms, 5), collapse = ", "))</lang>

## Racket

<lang racket>

1. lang racket

(require srfi/19)

(define long-months '(1 3 5 7 8 10 12)) (define days #(sun mon tue wed thu fri sat))

(define (week-day date)

``` (vector-ref days (date-week-day date)))
```

(define (five-weekends-a-month start end)

``` (for*/list ([year (in-range start (+ end 1))]
[month long-months]
[date (in-value (make-date 0 0 0 0 31 month year 0))]
#:when (eq? (week-day date) 'sun))
date))
```

(define weekends (five-weekends-a-month 1900 2100)) (define count (length weekends))

(displayln (~a "There are " count " weeks with five weekends.")) (displayln "The first five are: ") (for ([w (take weekends 5)])

``` (displayln (date->string w "~b ~Y")))
```

(displayln "The last five are: ") (for ([w (drop weekends (- count 5))])

``` (displayln (date->string w "~b ~Y")))
```

</lang> Output: <lang racket> There are 201 weeks with five weekends. The first five are: Mar 1901 Aug 1902 May 1903 Jan 1904 Jul 1904 The last five are: Mar 2097 Aug 2098 May 2099 Jan 2100 Oct 2100 </lang>

## REXX

This version uses the latest enhancements to the   DATE   built-in function (which some older REXX interpreters don't support).

Programming justification note: the inclusion of leapyear checking is present even though it wasn't needed as
February can be excluded from the criteria of having five weekends.   Having the leap year routine included
allows for a general-purpose stratagem of solving these types of problems without taking shortcuts to the
solution (although shortcuts are generally desirable).   If there is a change in the criteria, the support for
more (or less) checks can be supported easily, as well as supporting more criteria.
This version was written in such a way that it counts the number of days-of-the-week for each month, thereby
generalizing the problem without taking shortcuts specific to the task at hand.
Changing the task's requirements to find how many extended weekends (Fr-Sa-Su or Sa-Su-Mo) there are for
each month would entail changing only a single   if   statement. <lang rexx>/*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*/ !.=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, each year. */
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)
parse  upper  value   date('W', dat_, "I")    with    ? 3
wd.?=wd.?+1           /*? is the 1st 2 chars of weekday*/
end   /*d*/           /*WD.su = # of Sundays in a month*/
if wd.su\==5 | wd.fr\==5 | wd.sa\==5 then iterate  /*5 W.E.s?*/
say 'There are five weekends in'   y   date('M', dat_, "I")
haps=haps+1;   !.y=1        /*bump ctr; indicate yr 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; #=0

```         do y=yStart  to yStop;   if !.y  then iterate     /*skip if OK*/
#=#+1
say  'Year '    y    " doesn't have any five-weekend months."
end   /*y*/
```

say say "There are " # ' year's(#) "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*/</lang> output when using the default inputs

```There are five weekends in 1901 March
There are five weekends in 1902 August
There are five weekends in 1903 May
There are five weekends in 1904 January
There are five weekends in 1904 July
There are five weekends in 1905 December
There are five weekends in 1907 March
There are five weekends in 1908 May
There are five weekends in 1909 January
There are five weekends in 1909 October
There are five weekends in 1910 July
There are five weekends in 1911 December
There are five weekends in 1912 March
There are five weekends in 1913 August
There are five weekends in 1914 May
There are five weekends in 1915 January
There are five weekends in 1915 October
There are five weekends in 1916 December
There are five weekends in 1918 March
There are five weekends in 1919 August
There are five weekends in 1920 October
There are five weekends in 1921 July
There are five weekends in 1922 December
There are five weekends in 1924 August
There are five weekends in 1925 May
There are five weekends in 1926 January
There are five weekends in 1926 October
There are five weekends in 1927 July
There are five weekends in 1929 March
There are five weekends in 1930 August
There are five weekends in 1931 May
There are five weekends in 1932 January
There are five weekends in 1932 July
There are five weekends in 1933 December
There are five weekends in 1935 March
There are five weekends in 1936 May
There are five weekends in 1937 January
There are five weekends in 1937 October
There are five weekends in 1938 July
There are five weekends in 1939 December
There are five weekends in 1940 March
There are five weekends in 1941 August
There are five weekends in 1942 May
There are five weekends in 1943 January
There are five weekends in 1943 October
There are five weekends in 1944 December
There are five weekends in 1946 March
There are five weekends in 1947 August
There are five weekends in 1948 October
There are five weekends in 1949 July
There are five weekends in 1950 December
There are five weekends in 1952 August
There are five weekends in 1953 May
There are five weekends in 1954 January
There are five weekends in 1954 October
There are five weekends in 1955 July
There are five weekends in 1957 March
There are five weekends in 1958 August
There are five weekends in 1959 May
There are five weekends in 1960 January
There are five weekends in 1960 July
There are five weekends in 1961 December
There are five weekends in 1963 March
There are five weekends in 1964 May
There are five weekends in 1965 January
There are five weekends in 1965 October
There are five weekends in 1966 July
There are five weekends in 1967 December
There are five weekends in 1968 March
There are five weekends in 1969 August
There are five weekends in 1970 May
There are five weekends in 1971 January
There are five weekends in 1971 October
There are five weekends in 1972 December
There are five weekends in 1974 March
There are five weekends in 1975 August
There are five weekends in 1976 October
There are five weekends in 1977 July
There are five weekends in 1978 December
There are five weekends in 1980 August
There are five weekends in 1981 May
There are five weekends in 1982 January
There are five weekends in 1982 October
There are five weekends in 1983 July
There are five weekends in 1985 March
There are five weekends in 1986 August
There are five weekends in 1987 May
There are five weekends in 1988 January
There are five weekends in 1988 July
There are five weekends in 1989 December
There are five weekends in 1991 March
There are five weekends in 1992 May
There are five weekends in 1993 January
There are five weekends in 1993 October
There are five weekends in 1994 July
There are five weekends in 1995 December
There are five weekends in 1996 March
There are five weekends in 1997 August
There are five weekends in 1998 May
There are five weekends in 1999 January
There are five weekends in 1999 October
There are five weekends in 2000 December
There are five weekends in 2002 March
There are five weekends in 2003 August
There are five weekends in 2004 October
There are five weekends in 2005 July
There are five weekends in 2006 December
There are five weekends in 2008 August
There are five weekends in 2009 May
There are five weekends in 2010 January
There are five weekends in 2010 October
There are five weekends in 2011 July
There are five weekends in 2013 March
There are five weekends in 2014 August
There are five weekends in 2015 May
There are five weekends in 2016 January
There are five weekends in 2016 July
There are five weekends in 2017 December
There are five weekends in 2019 March
There are five weekends in 2020 May
There are five weekends in 2021 January
There are five weekends in 2021 October
There are five weekends in 2022 July
There are five weekends in 2023 December
There are five weekends in 2024 March
There are five weekends in 2025 August
There are five weekends in 2026 May
There are five weekends in 2027 January
There are five weekends in 2027 October
There are five weekends in 2028 December
There are five weekends in 2030 March
There are five weekends in 2031 August
There are five weekends in 2032 October
There are five weekends in 2033 July
There are five weekends in 2034 December
There are five weekends in 2036 August
There are five weekends in 2037 May
There are five weekends in 2038 January
There are five weekends in 2038 October
There are five weekends in 2039 July
There are five weekends in 2041 March
There are five weekends in 2042 August
There are five weekends in 2043 May
There are five weekends in 2044 January
There are five weekends in 2044 July
There are five weekends in 2045 December
There are five weekends in 2047 March
There are five weekends in 2048 May
There are five weekends in 2049 January
There are five weekends in 2049 October
There are five weekends in 2050 July
There are five weekends in 2051 December
There are five weekends in 2052 March
There are five weekends in 2053 August
There are five weekends in 2054 May
There are five weekends in 2055 January
There are five weekends in 2055 October
There are five weekends in 2056 December
There are five weekends in 2058 March
There are five weekends in 2059 August
There are five weekends in 2060 October
There are five weekends in 2061 July
There are five weekends in 2062 December
There are five weekends in 2064 August
There are five weekends in 2065 May
There are five weekends in 2066 January
There are five weekends in 2066 October
There are five weekends in 2067 July
There are five weekends in 2069 March
There are five weekends in 2070 August
There are five weekends in 2071 May
There are five weekends in 2072 January
There are five weekends in 2072 July
There are five weekends in 2073 December
There are five weekends in 2075 March
There are five weekends in 2076 May
There are five weekends in 2077 January
There are five weekends in 2077 October
There are five weekends in 2078 July
There are five weekends in 2079 December
There are five weekends in 2080 March
There are five weekends in 2081 August
There are five weekends in 2082 May
There are five weekends in 2083 January
There are five weekends in 2083 October
There are five weekends in 2084 December
There are five weekends in 2086 March
There are five weekends in 2087 August
There are five weekends in 2088 October
There are five weekends in 2089 July
There are five weekends in 2090 December
There are five weekends in 2092 August
There are five weekends in 2093 May
There are five weekends in 2094 January
There are five weekends in 2094 October
There are five weekends in 2095 July
There are five weekends in 2097 March
There are five weekends in 2098 August
There are five weekends in 2099 May
There are five weekends in 2100 January
There are five weekends in 2100 October

There were  201  occurrences of five-weekend months in years 1900──►2100

Year  1900  doesn't have any five-weekend months.
Year  1906  doesn't have any five-weekend months.
Year  1917  doesn't have any five-weekend months.
Year  1923  doesn't have any five-weekend months.
Year  1928  doesn't have any five-weekend months.
Year  1934  doesn't have any five-weekend months.
Year  1945  doesn't have any five-weekend months.
Year  1951  doesn't have any five-weekend months.
Year  1956  doesn't have any five-weekend months.
Year  1962  doesn't have any five-weekend months.
Year  1973  doesn't have any five-weekend months.
Year  1979  doesn't have any five-weekend months.
Year  1984  doesn't have any five-weekend months.
Year  1990  doesn't have any five-weekend months.
Year  2001  doesn't have any five-weekend months.
Year  2007  doesn't have any five-weekend months.
Year  2012  doesn't have any five-weekend months.
Year  2018  doesn't have any five-weekend months.
Year  2029  doesn't have any five-weekend months.
Year  2035  doesn't have any five-weekend months.
Year  2040  doesn't have any five-weekend months.
Year  2046  doesn't have any five-weekend months.
Year  2057  doesn't have any five-weekend months.
Year  2063  doesn't have any five-weekend months.
Year  2068  doesn't have any five-weekend months.
Year  2074  doesn't have any five-weekend months.
Year  2085  doesn't have any five-weekend months.
Year  2091  doesn't have any five-weekend months.
Year  2096  doesn't have any five-weekend months.

There are  29  years that haven't any five─weekend months in years 1900──►2100
```

### version for older REXXes

This version will work with any version of a REXX interpreter. <lang rexx>/*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*/ !.=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 ? */
say 'There are five weekends in'  y  word(@months,m)
haps=haps+1;   !.y=1         /*bump ctr; indicate yr 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

1. =0; say
```          do y=yStart  to yStop;  if !.y  then iterate     /*skip if OK*/
#=#+1
say  'Year '    y    " doesn't have any five-weekend months."
end   /*y*/
```

say say "There are " # ' year's(#) "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*/</lang> output is identical to the first version.

### version short and focussed at the task description

<lang rexx>/* 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)</lang> Output:

```Mar 1901 has 5 full weekends
Aug 1902 has 5 full weekends
May 1903 has 5 full weekends
Jan 1904 has 5 full weekends
Jul 1904 has 5 full weekends
Dec 1905 has 5 full weekends
...
Jul 2095 has 5 full weekends
Mar 2097 has 5 full weekends
Aug 2098 has 5 full weekends
May 2099 has 5 full weekends
Jan 2100 has 5 full weekends
Oct 2100 has 5 full weekends

201 occurrences of 5 full weekends in a month
29 years without 5 full weekends
```

### shorter version

<lang rexx>/*REXX program finds months with 5 weekends in them (given a date range)*/ month. =31 /*month days; Feb. is skipped. */ month.4=30; month.6=30; month.9=30; month.11=30 /*30-day months*/ yStart=1900; yStop=2100 /*define start and stop years. */ haps=0 /*num of five weekends happenings*/ !.=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 except Feb, each yr.*/
if m==2  then iterate       /*if month is February, skip it. */
do d=1  for month.m; dat_=y"-"right(m,2,0)'-'right(d,2,0)
parse  upper  value   date('W', dat_, "I")    with    ? 3
wd.?=wd.?+1           /*? is 1st 2 chars of tge weekday*/
end   /*d*/           /*WD.su=# of Sundays in the month*/
if wd.su\==5 | wd.fr\==5 | wd.sa\==5 then iterate  /*5 W.E.s?*/
say 'There are five weekends in'   y   date('M', dat_, "I")
haps=haps+1;   !.y=1        /*bump ctr; indicate yr has 5 WEs*/
end         /*m*/
end             /*y*/
```

say say 'There were ' haps " occurrences of five-weekend months in years" yStart'──►'yStop; say

1. =0
```        do y=yStart  to yStop;   if !.y  then iterate      /*skip if OK*/
#=#+1
say  'Year '     y     " doesn't have any five-weekend months."
end   /*y*/
```

say say "There are " # " years that haven't any five─weekend months in years" yStart'──►'yStop

```                                      /*stick a fork in it, we're done.*/</lang>
```

output is identical to the first REXX version.

### shorter and more focused

This REXX version takes advantage that a month with five full weekends must start on a Friday and have 31 days. <lang rexx>/*REXX program finds months with 5 weekends in them (given a date range)*/ month.=31; yStart=1900; yStop=2100 /*month days; range of years. */ month.2=0; month.4=0; month.6=0; month.9=0; month.11=0 /*¬31 day months*/ haps=0 /*num of five weekends happenings*/ !.=0 /*if a year has any five-weekends*/

```    do y=yStart  to yStop             /*process the years specified.   */
do m=1  for 12;  if month.m==0  then iterate  /*test 31-day mons*/
dat_=y"-"right(m,2,0)'-01'     /*get date in the proper format. */
if left(date('W',dat_,"I"),2)\=='Fr'  then iterate     /*Friday?*/
say 'There are five weekends in'   y   date('M', dat_, "I")
haps=haps+1;   !.y=1           /*bump ctr; indicate yr has 5 WEs*/
end   /*m*/
end      /*y*/
```

say say 'There were ' haps " occurrences of five-weekend months in years" yStart'──►'yStop; say

1. =0
```      do y=yStart  to yStop;   if !.y  then iterate        /*skip if OK*/
#=#+1
say  'Year '     y     " doesn't have any five-weekend months."
end   /*y*/
```

say say "There are " # " years that haven't any five─weekend months in years" yStart'──►'yStop

```                                      /*stick a fork in it, we're done.*/</lang>
```

output is identical to the first REXX version.

## Ruby

<lang ruby>require 'date'

1. if the last day of the month falls on a Sunday and the month has 31 days,
2. 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.first(5).map { |d| d.strftime("%b %Y") } puts "..." puts dates.last(5).map { |d| d.strftime("%b %Y") }

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(", ")</lang>

Output

```There are 201 months with 5 weekends from 1900 to 2100:
Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100
There are 29 years without months with 5 weekends:
1900, 1906, 1917, 1923, 1928, 1934, 1945, 1951, 1956, 1962, 1973, 1979, 1984,
1990, 2001, 2007, 2012, 2018, 2029, 2035, 2040, 2046, 2057, 2063, 2068, 2074,
2085, 2091, 2096```

## Run BASIC

<lang runbasic>preYear = 1900 for yyyy = 1900 to 2100

```  for mm     = 1 to 12                ' go thru all 12 months
dayOne\$ = mm;"-01-";yyyy         ' First day of month
n       = date\$(dayOne\$)         ' Days since 1700
dow     = 1 + (n mod 7)          ' Day of Week month begins
m1      = mm                     '
n1      = n + 27                 ' find end of month starting with 27th day
while   m1 = mm                  ' if month changes we have the end of the month
n1   = n1 + 1
n\$   = date\$(n1)
m1   = val(left\$(n\$,2))
wend
mmDays  = n1 - n                 ' Days in the Month
if dow  = 4 and mmDays = 31 then ' test for 5 weeks
count = count + 1
print using("###",count);" ";yyyy;"-";left\$("0";mm,2)
end if
```
```  next mm
if preCount = count then
noCount = noCount + 1             ' count years that have none
print yyyy;" has none ";noCount
end if
preCount = count
```

next yyyy</lang>

Output

```1900 has none 1
1 1901-03
2 1902-08
3 1903-05
4 1904-01
5 1904-07
6 1905-01
1906 has none 2
7 1907-03
........
196 2095-07
2096 has none 29
197 2097-03
198 2098-08
199 2099-05
200 2100-01
201 2100-01```

## Seed7

<lang seed7>\$ include "seed7_05.s7i";

``` include "time.s7i";
```

const proc: main is func

``` local
var integer: months is 0;
var time: firstDayInMonth is time.value;
begin
for firstDayInMonth.year range 1900 to 2100 do
for firstDayInMonth.month range 1 to 12 do
if daysInMonth(firstDayInMonth) = 31 and dayOfWeek(firstDayInMonth) = 5 then
writeln(firstDayInMonth.year <& "-" <& firstDayInMonth.month lpad0 2);
incr(months);
end if;
end for;
end for;
writeln("Number of months:" <& months);
end func;</lang>
```

Output:

```1901-03
1902-08
1903-05
1904-01
1904-07
1905-12
...
2095-07
2097-03
2098-08
2099-05
2100-01
2100-10
Number of months:201
```

## Tcl

<lang tcl>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 ","]</lang> Output:

```There are 201 months with five weekends
Mar 1901
Aug 1902
May 1903
Jan 1904
Jul 1904
...
Mar 2097
Aug 2098
May 2099
Jan 2100
Oct 2100
There are 29 years without any five-weekend months
1900,1906,1917,1923,1928,1934,1945,1951,1956,1962,1973,1979,1984,1990,2001,2007,2012,2018,2029,2035,2040,2046,2057,2063,2068,2074,2085,2091,2096
```

## TUSCRIPT

<lang tuscript> \$\$ MODE TUSCRIPT LOOP year=1900,2100

```LOOP month="1'3'5'7'8'10'12"
SET dayofweek=DATE (number,1,month,year,nummer)
IF (dayofweek==5) PRINT year,"-",month
ENDLOOP
```

ENDLOOP </lang> Output:

```1901-3
1902-8
1903-5
1904-1
1904-7
1905-12
1907-3
1908-5
1909-1
1909-10
1910-7
1911-12
1912-3
1913-8
1914-5
1915-1
1915-10
1916-12
1918-3
1919-8
1920-10
1921-7
1922-12
1924-8
1925-5
1926-1
1926-10
1927-7
1929-3
1930-8
1931-5
1932-1
1932-7
1933-12
1935-3
1936-5
1937-1
1937-10
1938-7
1939-12
1940-3
1941-8
1942-5
1943-1
1943-10
1944-12
1946-3
1947-8
1948-10
1949-7
1950-12
1952-8
1953-5
1954-1
1954-10
1955-7
1957-3
1958-8
1959-5
1960-1
1960-7
1961-12
1963-3
1964-5
1965-1
1965-10
1966-7
1967-12
1968-3
1969-8
1970-5
1971-1
1971-10
1972-12
1974-3
1975-8
1976-10
1977-7
1978-12
1980-8
1981-5
1982-1
1982-10
1983-7
1985-3
1986-8
1987-5
1988-1
1988-7
1989-12
1991-3
1992-5
1993-1
1993-10
1994-7
1995-12
1996-3
1997-8
1998-5
1999-1
1999-10
2000-12
2002-3
2003-8
2004-10
2005-7
2006-12
2008-8
2009-5
2010-1
2010-10
2011-7
2013-3
2014-8
2015-5
2016-1
2016-7
2017-12
2019-3
2020-5
2021-1
2021-10
2022-7
2023-12
2024-3
2025-8
2026-5
2027-1
2027-10
2028-12
2030-3
2031-8
2032-10
2033-7
2034-12
2036-8
2037-5
2038-1
2038-10
2039-7
2041-3
2042-8
2043-5
2044-1
2044-7
2045-12
2047-3
2048-5
2049-1
2049-10
2050-7
2051-12
2052-3
2053-8
2054-5
2055-1
2055-10
2056-12
2058-3
2059-8
2060-10
2061-7
2062-12
2064-8
2065-5
2066-1
2066-10
2067-7
2069-3
2070-8
2071-5
2072-1
2072-7
2073-12
2075-3
2076-5
2077-1
2077-10
2078-7
2079-12
2080-3
2081-8
2082-5
2083-1
2083-10
2084-12
2086-3
2087-8
2088-10
2089-7
2090-12
2092-8
2093-5
2094-1
2094-10
2095-7
2097-3
2098-8
2099-5
2100-1
2100-10
```

## XPL0

<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations

proc WeekDay(Year, Month, Day); \Return day of week (0=Sat 1=Sun..6=Fri) int Year, Month, Day; [if Month<=2 then [Month:= Month+12; Year:= Year-1]; return rem((Day + (Month+1)*26/10 + Year + Year/4 + Year/100*6 + Year/400) / 7); ]; \WeekDay

int MonthTbl, Year, I, C; [MonthTbl:= [1, 3, 5, 7, 8, 10, 12]; \months with 31 days C:= 0; for Year:= 1900 to 2100 do

``` for I:= 0 to 6 do                             \for all the 31-day months...
if WeekDay(Year, MonthTbl(I), 1) = 6 then   \first of month is a Friday
[C:= C+1;                               \count this year
if C<=5 or C>201-5 then                 \show first 5 and last 5 years
[IntOut(0, Year);  ChOut(0, ^ );
IntOut(0, MonthTbl(I));  CrLf(0);
];
];
```

IntOut(0, C); CrLf(0); \show number of years

\Count and show all years that don't have any 5-weekend months C:= 0; for Year:= 1900 to 2100 do

```       [for I:= 0 to 6 do                      \for all the 31-day months...
if WeekDay(Year, MonthTbl(I), 1) = 6 \Friday\ then
I:= 10;                         \bail out of 'for' loop
if I<10 then                            \'for' loop completed
[if (C&\$F) = 0 then CrLf(0);    \(format 16 years per line)
C:= C+1;                        \ without finding a 5-weekend
IntOut(0, Year);  ChOut(0, ^ ); \ so show the year
];
];
```

CrLf(0); IntOut(0, C); CrLf(0); \show number of years ]</lang>

Output:

```1901 3
1902 8
1903 5
1904 1
1904 7
2097 3
2098 8
2099 5
2100 1
2100 10
201

1900 1906 1917 1923 1928 1934 1945 1951 1956 1962 1973 1979 1984 1990 2001 2007
2012 2018 2029 2035 2040 2046 2057 2063 2068 2074 2085 2091 2096
29
```