# Number of first days of the month equals to Mondays

21 views (last 30 days)

Show older comments

Hello guys,

I have an assignment that states: "Write a function called day_counter that returns the number of Mondays that fell on the first day of the month in a given year between 1776 and 2016 inclusive where the requested year is the only input to your function and it is a positive integer scalar. Note that a leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400. In a leap year, February has 29 days. You are not allowed to use the datenum built-in function."

Now, I am having a problem with this code:

function [ numMon ] = day_counter( givenYear )

startYear = 1776;

totalDaysYear=0;

% First day of 1776 is Monday.

numMon=1; % Jan 1st,1776 was Monday.

% Calculate leap year for input year.

for countYear= startYear:givenYear

% Determine whether it is leap year.

if mod(countYear, 4)==0 || (mod(countYear, 100)==0 && mod(countYear, 400)==0)

Febdays=29;

else

Febdays=28;

end

% Set the corresponding number of days per month.

monthDays = {'Jan', 'Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dic'; ...

31,Febdays,31,30,31,30,31,31,30,31,30,31};

% Sum all days until you complete a year. It the sum per month is

% devisible by 7 (since the initial condition), then is it Monday.

for ii = 1:length(monthDays(1,:))

totalDaysYear = (totalDaysYear) + monthDays{2,ii};

if rem(totalDaysYear,7)==0

numMon = numMon+1;

end

end

totalDaysYear= totalDaysYear-1;

% Calculate the number of first day of a month equal to Monday PER EACH

% YEAR, which mean the variable numMon has to be reset.

Mondays = numMon;

% Verify whether first day of the input year is Monday.

firstDayYear = mod(totalDaysYear+1,7);

if firstDayYear==0

numMon = 1;

else

numMon=0;

end

end

numMon = Mondays;

end

I cannot find the "bug" causing an error in the output variable "totalDaysYear" (total days accumulated yearly since 1776). A correct output for year 1776 is 3, for 1800 is 2, and for year 2000 is 2. I already solved the problem using the built-in functions "weekday" and "datetime", but I would like to do it in this way.

I would really appreciate some guidance or help in order to improve coding.

Thank you in advance.

Jorge

##### 1 Comment

Geoff Hayes
on 26 Feb 2018

Jorge - I don't understand this comment

% Sum all days until you complete a year. It the sum per month is

% devisible by 7 (since the initial condition), then is it Monday.

How do you know this is true?

### Answers (4)

Srishti Saha
on 13 May 2018

I have written the following function and it has worked perfectly for me:

%problem day counterfunction n = day_counter(year)

%creating a vector for number of days in a month starting January

months = [31 28 31 30 31 30 31 31 30 31 30 31];

start = 1776;

y = year - start; % computing number of years since 1776

% number of days since January 1, 1776:

ndays = y*365 + ceil(y/4) - floor((year-1)/100) + floor(start/100) + floor((year-1)/2000);

% if it is a leap year, adjust nbr of days in February to 29; condition for checking a leap year:

if mod(year,4) == 0 && (mod(year,100) ~= 0 || mod(year,400) == 0)

months(2) = 29;

end

%for previous month

months = [0 cumsum(months(1:end-1))];

n = sum(mod(ndays+months,7) == 0); %for Mondays

end

##### 1 Comment

Jan
on 26 Feb 2018

Edited: Jan
on 26 Feb 2018

This does not define a leap year:

if mod(countYear, 4)==0 || (mod(countYear, 100)==0 && mod(countYear, 400)==0)

You want:

if mod(countYear, 4)==0 && (mod(countYear, 100)~=0 || mod(countYear, 400)==0)

By the way: Do you see, that the line is easier to read with a shorter name of the variable:

if mod(Y, 4) == 0 && (mod(Y, 100) ~= 0 || mod(Y, 400) == 0)

The is no need to process former years completely. Better create a subfunction to detect leap years:

function L = isLeap(Y)

L = mod(countYear, 4)==0 & (mod(countYear, 100)~=0 | mod(countYear, 400)==0);

end

Here you use & instead of && to allow a vector input. Then for the year Y you can determine the day of the 01-January:

YL = 1776:(Y-1);

ALdays = 366 * YL + 365 * ~YL + 1;

Now a mod() is enough.

##### 2 Comments

Jan
on 5 Nov 2018

Mosen shk
on 3 Jan 2019

##### 1 Comment

Walter Roberson
on 3 Jan 2019

RAMAKANT SHAKYA
on 7 Feb 2019

function counter=day_counter(y)

counter=0;

year=rem(y,100); % no of years in century

lp=fix(year/4); %leap year

if y~=1900 && (rem(y,4)==0 || rem(y,400)==0)

mday={[1:31],[1:29],[1:31],[1:30],[1:31],[1:30],[1:31],[1:31],[1:30],[1:31],[1:30],[1:31]};%days in the months...

mcode={0,3,4,0,2,5,0,3,6,1,4,6};%code are assign for months

daycode={1,2,3,4,5,6,0};% start from sun,mon....

else

mday={[1:31],[1:28],[1:31],[1:30],[1:31],[1:30],[1:31],[1:31],[1:30],[1:31],[1:30],[1:31]};%code are assign for months

mcode={1,4,4,0,2,5,0,3,6,1,4,6};%code are assign for months

daycode={1,2,3,4,5,6,0};% start from sun,mon....

end

%code for the centuries

%1700-1799 code is 4

%1800-1899 code is 2

%1900-1999 code is 0

%2000-2099 code is 6

%2100-2199 code is 4 and this pattern continue in same manner

function cen= century(y)

if y>=1700 && y<=1799

cen=4;

elseif y>=1800 && y<=1899

cen=2;

elseif y>=1900 && y<=1999

cen=0;

elseif y>=2000 && y<=2099

cen=6;

end

end

cen=century(y);

firstd=rem((1+mcode{1}+year+lp+cen),7);% to find the day on 1 Jan of given year

%reminder =(date+monthcode+year+leap year till that year)/7

dday={};

for r=1:12 % for months

for c=mday{r}(1:end) % for dates of respective months

dday{r}(1,c)=firstd; %starting from january

firstd=firstd+1; % for next day on next loop of c means next day

firstd=rem(firstd,7); % days of week

end

if dday{r}(1,1)==2 %if first day of month is monday

counter=counter+1; % starting counting

end

end

end

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!