MATLAB Answers

Number of first days of the month equals to Mondays

16 views (last 30 days)
Jorge Briceño
Jorge Briceño on 26 Feb 2018
Answered: RAMAKANT SHAKYA on 7 Feb 2019
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
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?

Sign in to comment.

Answers (4)

Srishti Saha
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

Walter Roberson
Walter Roberson on 13 May 2018
We discourage giving complete answers for homework questions.

Sign in to comment.


Jan
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

Adarsh Agarwal
Adarsh Agarwal on 4 Nov 2018
Sir, can you please provide the solution for this question?
Jan
Jan on 5 Nov 2018
@Adarsh Agarwal: You find a working solution in this thread already and my answer contains instruction to solve the problem also. So please try to implement it by your own and ask a specific question on demand.

Sign in to comment.


Mosen shk
Mosen shk on 3 Jan 2019
you can use weekday function to define which day is the start of each month. this gives you a logical array and you just need to define how many logical '1' exist in the response

  1 Comment

Walter Roberson
Walter Roberson on 3 Jan 2019
True. However, weekday() requires a serial date number as input, and you do not have that to start; or weekday() can take a date character vector, but I wonder if that would be considered to be against the rules about not using datenum() ?

Sign in to comment.


RAMAKANT SHAKYA
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

Sign in to comment.


Translated by