Number of first days of the month equals to Mondays

조회 수: 2 (최근 30일)
Jorge Briceño
Jorge Briceño 2018년 2월 26일
답변: RAMAKANT SHAKYA 2019년 2월 7일
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
Geoff Hayes
Geoff Hayes 2018년 2월 26일
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?

댓글을 달려면 로그인하십시오.

답변 (4개)

Srishti Saha
Srishti Saha 2018년 5월 13일
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
Walter Roberson
Walter Roberson 2018년 5월 13일
We discourage giving complete answers for homework questions.

댓글을 달려면 로그인하십시오.


Jan
Jan 2018년 2월 26일
편집: Jan 2018년 2월 26일
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
Adarsh Agarwal
Adarsh Agarwal 2018년 11월 4일
Sir, can you please provide the solution for this question?
Jan
Jan 2018년 11월 5일
@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.

댓글을 달려면 로그인하십시오.


Mosen shk
Mosen shk 2019년 1월 3일
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
Walter Roberson
Walter Roberson 2019년 1월 3일
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() ?

댓글을 달려면 로그인하십시오.


RAMAKANT SHAKYA
RAMAKANT SHAKYA 2019년 2월 7일
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

카테고리

Help CenterFile Exchange에서 Startup and Shutdown에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by