Number of first days of the month equals to Mondays

7 views (last 30 days)
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
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

Categories

Find more on Dates and Time in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!