Five weekends

From Rosetta Code
Revision as of 19:48, 12 December 2010 by rosettacode>Gerard Schildberger (→‎{{header|REXX}}: added a version that'll work with any REXX interpreter.)
Task
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.

The task

  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).

Ada

<lang Ada> with Ada.Text_IO; use Ada.Text_IO; with Ada.Calendar.Formatting; use Ada.Calendar;

use Ada.Calendar.Formatting;

procedure Five_Weekends is

  Months : Natural := 0;

begin

  for Year in Year_Number range 1901..2100 loop
     for Month in Month_Number range 1..12 loop
        begin
           if Day_Of_Week (Formatting.Time_Of (Year, Month, 31)) = Sunday then
              Put_Line (Year_Number'Image (Year) & Month_Number'Image (Month));
              Months := Months + 1;
           end if;
        exception
           when Time_Error =>
              null;
        end;
     end loop;
  end loop;
  Put_Line ("Number of months:" & Integer'Image (Months));

end Five_Weekends; </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

D

<lang d>import std.gregorian ; // this module currently work in progress import std.stdio, std.algorithm, std.array, std.range ;

Date[] m5w(Date start = Date(1900,1,1), Date end = Date(2100,12,31) ) {

   Date[] res ;    
   for(Date when = Date(start.year, start.month, 1) ; // adjust to 1st day
       when < end ; 
       when = Date(when.year, 1 + when.month, 1)) {
               
       if(when.endOfMonthDay == 31)   // Such month must has 3 + 4*7 
           if(when.dayOfWeek == 5 )   // days and start at friday
               res ~= when ;          // for 5 FULL weekends.
   }
   return res ;

}

bool noM5wByYear(int year) {

   return (m5w(Date(year,1,1), Date(year,12,31)).length == 0 ) ;

}

void main() {

   auto m = m5w() ; // use default input       
   writefln("There are %d months of which the first and last five are:",
       m.length) ;     
   foreach(d;m[0..5]~m[$-5..$]) 
       writefln("%s", d.toSimpleString[0..$-2]) ;
   auto noM5w = filter!(noM5wByYear)(iota(1900,2101)) ;
   writefln("There are %d years in the range that do not have "
            "months with five weekends", array(noM5w).length) ;

}</lang>

output match python one.

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 := [ ];
 badL := [ ];
 for y in [y1 .. y2] do
   yL := [ ];
   for m in [1, 3, 5, 7, 8, 10, 12] do
     if WeekDay([1, m, y]) = "Fri" then
       d := StringDate([1, m, y]);
       Add(yL, d{[4 .. 11]});
     fi;
   od;
   if Length(yL) = 0 then
     Add(badL, y);
   else
     Append(L, yL);
   fi;
 od;
 return [ L, badL ];

end;

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

  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>

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.

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

<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

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

Perl 6

Works with: Rakudo version 2010-10

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

  1. Note: [@happy.end X- ^5].reverse is a workaround; Rakudo does not yet allow [*-5..*].

my @years = 1900 .. 2100; my @ym = @years X < 01 03 05 07 08 10 12 >; # Months with 31 days

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

say 'Happy month count: ', +@happy; say 'First happy months: '~ @happy[^5]; say 'Last happy months: '~ @happy[@happy.end X- ^5].reverse; 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)

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


REXX

version 1

This version uses the latest enhancements to the DATE built-in function.
Not all REXX interpreters support this feature.

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 leapyear routine included
allows for a general-purpose strategem of solving these types of problems without taking shortcuts to the
solution (although shortcuts are generaly desireable). If there is a change in the criteria, the
support for more (or less) checks can be supported easily, as well as supporting more criterium. <lang rexx> /*REXX program finds months with 5 weekends in them (given a date range)*/

parse arg yStart yStop . if yStart== then yStart=1900 if yStop == then yStop =2100 years=ystop-yStart+1 month. =31 /*month days, Feb. is done later.*/ month.4 =30 month.6 =30 month.9 =30 month.11=30 haps=0 /*num of five weekends happenings*/ yr5.=0 /*if a year has any five-weekends*/

 do y=yStart to yStop                 /*process the years specified.   */
     do m=1 for 12;  mm=right(m,2,0)  /*process each month in each year*/
     if m==2 then month.2=28+leapyear(y)    /*handle num of days in Feb*/
     wd.=0
            do d=1 for month.m;  dd=right(d,2,0)
            dat_=y"-"mm'-'dd
            _=left(date('W',dat_,"I"),2);  upper _
            wd._=wd._+1               /* _ is first 2 chars of weekday.*/
            end   /*d*/
     if wd.su\==5 | wd.fr\==5 | wd.sa\==5 then iterate   /*5 weekends ?*/
     haps=haps+1                                         /*bump counter*/
     say 'There are five weekends in' y date('M',dat_,"I")
     yr5.y=1                          /*indicate this year has one.    */
     end          /*m*/
 end              /*y*/

say say 'There were' haps "occurance"s(haps) 'of five-weekend months in',

    "year"s(years) yStart'-->'yStop

say no5s=0

   do y=yStart to yStop
   if yr5.y then iterate
   no5s=no5s+1
   say y "doesn't have any five-weekend months."
   end

say say "There are" no5s 'year's(no5s),

   "that haven't any five-weekend months in year"s(years) yStart'-->'yStop

exit


/*─────────────────────────────────────LEAPYEAR subroutine──────────────*/ leapyear: procedure; 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 leapyear.*/ return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */


/*─────────────────────────────────────S subroutine (for plurals)───────*/ s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) </lang> Output:

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 occurances of five-weekend months in years 1900-->2100

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

There are 29 years that haven't any five-weekend months in years 1900-->2100

version 2

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)*/

parse arg yStart yStop . if yStart== then yStart=1900 if yStop == then yStop =2100 years=ystop-yStart+1 month. =31 /*month days, Feb. is done later.*/ month.4 =30 month.6 =30 month.9 =30 month.11=30 haps=0 /*num of five weekends happenings*/ yr5.=0 /*if a year has any five-weekends*/ @months='January February March April May June July',

       'August September October November December'
 do y=yStart to yStop                 /*process the years specified.   */
     do m=1 for 12                    /*process each month in each year*/
     wd.=0
     if m==2 then month.2=28+leapyear(y)    /*handle num of 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 (Sunday),  2 (Monday) ...*/
            end   /*d*/
     if wd.1\==5 | wd.6\==5 | wd.7\==5 then iterate      /*5 weekends ?*/
     haps=haps+1                                         /*bump counter*/
     say 'There are five weekends in' y word(@months,m)
     yr5.y=1                          /*indicate this year has one.    */
     end          /*m*/
 end              /*y*/

say say 'There were' haps "occurance"s(haps) 'of five-weekend months in',

    "year"s(years) yStart'-->'yStop

say no5s=0

   do y=yStart to yStop
   if yr5.y then iterate
   no5s=no5s+1
   say y "doesn't have any five-weekend months."
   end

say say "There are" no5s 'year's(no5s),

   "that haven't any five-weekend months in year"s(years) yStart'-->'yStop

exit


/*─────────────────────────────────────DOW (day of week) subroutine─────*/ dow: procedure; 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; 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 leapyear.*/ return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */


/*─────────────────────────────────────S subroutine (for plurals)───────*/ s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) </lang>

Ruby

<lang ruby># if the last day of the month falls on a Sunday and the month has 31 days,

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

end

puts "There are #{dates.size} months with 5 weekends from 1900 to 2100:" puts dates[0, 5].map { |d| d.strftime("%b %Y") }.join("\n") puts "..." puts dates[-5, 5].map { |d| d.strftime("%b %Y") }.join("\n")

years_with_5w = dates.map(&:year)

years = (1900...2100).to_a - years_with_5w

puts "There are #{years.size} years without months with 5 weekends:" puts years.join(", ")</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

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