Counting Sundays in c++; - c++

You are given the following information, but you may prefer to do some research for yourself.
1 Jan 1900 was a Monday. Thirty days has September, April, June and November. All the rest have thirty-one, Saving February alone, Which has twenty-eight, rain or shine. And on leap years, twenty-nine. A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
I don't seem to get the right answer or find the bug. I get the answer 85.
int main(){
int month[12]={31,0,31,30,31,30,31,31,30,31,30,31};
int j=0;
int i= 1901;
int day=1;
int sunday=0;
for(i=1901;i<2001;i++) {
if( i % 4==0 ){
month[1]=29;
}
else {
month[1]=28;
}
for (j=0;j<12;j++){
if (day % 7 ==0){
sunday++;
}
day+=month[j];
j++;
}
}
cout<< sunday<<endl;
cin.ignore();
return 0;
}

Bisides what Bathsheba already pointed out in his answer You are also skipping every other month. In your for loop you increment j at the end of the loop and then j will get incremented again at the start of the next loop.
for (j=0;j<12;j++){
if (day % 7 ==0){
sunday++;
}
day+=month[j];
j++;<--------------get rid of this
}

Given that the normal definition of the 20th century is from 1-Jan-1900 to 31-Dec-1999, consider changing the loop to for (i = 1900; i < 2000; ++i).
If you need the range to be from 1-Jan-1901 to 31-Dec-2000 then note that 1-Jan-
1901 was a Tuesday and so the starting value of day needs to be 2.
You also have a spurious j++; in your month iteration (acknowledge #NathanOliver)
Other than that, the algorithm looks fine. Although I don't like the continuous writing to month.

Related

Method to calculate business days

I have an exercice, which I am having a little trouble with.
I must create a calculator which takes two parameters: Start date and days to add (except saturday and sunday, only business days, from monday to friday). Another thing is that the sum has to include the start date.
E.g. let's take the start day July 12th 2016, and add 8 days, which correspond to July 21th 2016 (Saturday and Sunday excluded, and Tuesday, July 21th 2016 is counted as one day).
I hope I'm clear.
I tried to code something, but it is not working.
// rStringGridEd1->IntCells[3][row] is a custom stringgrid
// and correspond to the number of days to add, j is the
// counter for the loop
while (j < rStringGridEd1->IntCells[3][row])
{
if (DayOfWeek(date) != 1 || DayOfWeek(date) !=7)
{
// if current date (TDate date = "12/07/16") is not Saturday or Sunday increment date by one day
date++;
}
else if(DayOfWeek(date) == 1)
{
//If date correspond to sunday increment the date by one and j the counter by one
date=date+1;
j++;
}
else if(DayOfWeek(date) == 7)
{
//If date correspond to saturday increment the date by two days and j the counter by one
date=date+2;
j++;
}
j++;
}
Can anyone help me, please?
Here is what Lee Painton's excellent (and up-voted) answer would look like using this free, open-source C++11/14 date library which is built on top of <chrono>:
#include "date.h"
#include <iostream>
date::year_month_day
get_end_job_date(date::year_month_day start, date::days length)
{
using namespace date;
--length;
auto w = weeks{length / days{5}};
length %= 5;
auto end = sys_days{start} + w + length;
auto wd = weekday{end};
if (wd == sat)
end += days{2};
else if (wd == sun)
end += days{1};
return end;
}
You could exercise it like this:
int
main()
{
using namespace date::literals;
std::cout << get_end_job_date(12_d/jul/2016, date::days{8}) << '\n';
}
Which outputs:
2016-07-21
This simplistic calculator has a precondition that start is not on a weekend. If that is not a desirable precondition then you could detect that prior to the computation and increment start internally by a day or two.
The date library takes care of things like the relationship between days and weeks, and how to add days to a date. It is based on very efficient (non-iterative) algorithms shown and described here.
If you aren't required to use a loop then you might want to consider refactoring your solution with a simpler calculation. Consider, for example, that every five business days automatically adds seven days to the date. Thus using the quotient and remainder of the days to add should tell you how many total days to add to your date variable without resorting to a brute force loop.
Since it's an exercise I won't get into specifics of code, but a few things to consider might be how you can figure out what day of the week you end on knowing the day that you started on. Also, if you end on a friday what happens with the weekend that immediately follows it.

year duration algorithm in c++

I'm making a program that needs the duration (in time_t) of a year.
In other ways, time_t of DD/MM/YYYY + duration = time_t of DD/MM/YYYY+1
So it may not always be 365 days (and 29/02/2012 will become 28/02/2013)
Here's the algorithm I came with :
if YEAR is leap than
if we are before the 29th feb' than return 365+1 days
else if we are the 29th feb' than return 365-1 days
else return 365 days
else if YEAR+1 is leap than
if we are before or the 28th feb' than return 365 days
else return 365+1 days
else return 365 days
Here, a day is 60 * 60 * 24 seconds
This algorithm seems to work. But I was wondering if there were another way to do this without all theses conditions and only 2 possible return values, or just some "trick" to optimize the thing.
I tried to increment tm_year from the struct tm like this :
// t is the input time_t
struct tm Tm (*localtime(&t));
if (Tm.tm_mon == 2 && Tm.tm_mday == 29) --Tm.tm_mday;
++Tm.tm_year;
return mktime(&Tm) - t;
But the result isn't what I want, I got -1 hour, or -25...
I guess it's because a year is not exactly 365 * 24 * 60 * 60.
I would use Boost for this, since it already implements what you are looking for:
#include <iostream>
#include <boost/date_time/gregorian/gregorian_types.hpp>
namespace date = boost::gregorian;
int main() {
date::date_period dp(date::date(2012, 6, 4), date::date(2013, 6, 4));
long days = dp.length().days();
std::cout << "Days between dates: " << days << std::endl;
}
If you wanted more precision, then you could use posix_time from Boost too:
namespace ptime = boost::posix_time;
...
ptime::ptime t1(date::date(2012, 6, 4), ptime::hours(0));
ptime::ptime t2(date::date(2013, 6, 4), ptime::hours(0));
ptime::time_duration td = t2 - t1;
std::cout << "Milliseconds: " << td.total_milliseconds() << std::endl;
Typically time_t is measured in seconds. Therefore, you would just need to call to td.total_seconds() to obtain the value that you are looking for.
if YEAR is leap than
if we are before the 29th feb' than return 365+1 days
else if we are the 29th feb' than return 365-1 days
else return 365 days
else if YEAR+1 is leap than
if we are before or the 28th feb' than return 365 days
else return 365+1 days
else return 365 days
simplifies to:
if (YEAR is leap)
if (< 29th Feb) return 365+1
if (= 29th Feb) return 365-1
else if (YEAR+1 is leap)
if (> 29th Feb) return 365+1
return 365
But why would you want to do this? It's much better to have readable code than "trick" optimizations.
As #betabandido has suggested, something like date(year+1, mon, day) - date(year, mon, day) would be much simpler, far more readable and able to handle leap years, leap seconds and September missing 11 days.
The length of a solar year is not a fixed number. The Gregorian calendar has invented a method to compensate for leap years which is not entirely precise. That goes "a year is a leap year if it is divisible by 4, unless it is divisible by 100, but is leap again if it is divisible by 400.
We in Iran have a more precise calendar, in which the years change the second Earth makes a full circle around the sun. In the same link you can see the average solar year as 365.2422 days and mean interval between spring equinoxes as 365.2424 days.
In this link more details are given about the length of the solar year (tropical year) in seconds.

View Years Alive in Months

I am trying to create a program that finds out how many months they have been alive, but have been running into some issues. Here is my function so far:
int getResult(int year, month, day, endResult)
{
int thisYear, thisMonth, thisDay;
year = thisYear - year;
year *= 12;
}
And what I'm trying to accomplish would show an output like:
Output:
What year were you born?
1989
What month were you born?
5
What day were you born?
23
You are x months old.
I was going to continue with months but then I realized, what if the month they were born is in after this month or before? So, if anyone has any tips on how to calculate that, I'd appreciate it.
Let's see. First, let's say now is:
year_now and month_now
and your birthday is:
year_birth and month_birth
Now, we go case by case:
month_now == month_birth: as you have already computed:
months_old = (year_now-year_birth)*12
month_now > month_birth: easily, you have:
months_old = (year_now-year_birth)*12 + (month_now-month_birth)
month_now < month_birth: in this case, (year_now-year_birth)*12 gives you more months then necessary, and you have to subtract:
months_old = (year_now-year_birth)*12 - (month_birth-month_now)
Now if you look carefully, you will see that they are all in fact the same formula:
months_old = (year_now-year_birth)*12 + (month_now-month_birth)
(in the third case, month_now-month_birth is negative)
months = (thisyear-years)*12+(thisMonth-months)
if(months < 0)
System.out.println("Invalid info")
else{
//DO YOUR THANG BRO
}

C++ add 1 year to date

This is how im generating my date i want to add 1 year to it. Thanks in advance.
char tmpbuf[128];
time_t ltime;
struct tm *today;
stringstream reD;
string todayDate;
time( &ltime );
today = localtime( &ltime );
strftime( tmpbuf, 128,"%Y-%m-%d_%H:%M:%S", today );
reD << tmpbuf;
reD >> todayDate;
boost::replace_all(todayDate, "_", " ");
cout << todayDate << endl;
OK ive decided to go with boost since it will be easier to add days, so 2 examples i need one to add 1 year, and one to add 14 days, heres what i have so fare
#include "boost/date_time.hpp"
#include "boost/date_time/local_time/local_time.hpp"
using namespace boost::posix_time;
using namespace boost::local_time;
int main(){
local_date_time t = local_sec_clock::local_time(time_zone_ptr());
local_time_facet* lf(new local_time_facet("%Y-%m-%d_%H:%M:%S"));
std::cout.imbue(std::locale(std::cout.getloc(), lf));
std::cout << t << std::endl;
return 0;
}
Edit putting time into string
stringstream reD;
reD.imbue(locale(reD.getloc(), lf));
reD << t;
bthis = reD.str();
cout << bthis << endl;
If you're using C++, I highly recommend boost::date_time to take the leg-work out of this.
There is no such thing as "adding a year".
Let us suppose that you go into incrementing the year by 1, after all, that is what you are aiming for.
Unfortunately, there are some inconsistencies in the way we deal with the time:
leap years: if you are on February 29th, 2008, what does adding a year mean ? February 28th, 2009 or March 1st, 2009 ? (Hint: changing the month is very confusing for the user of a calendar)
leap seconds: on June 30th or December 31th, a second or two might be added to the last minute, making that minute 61 or 62 seconds. (Hint: once again, changing the day is confusing)
special events: like the calendar re-adjustment that occurred in 1582, where Thursday, October 4, 1582 was followed by Friday, October 15, 1582, resulting in a full 10 days loss.
The problem here, is not really in "adding" a year, you can always choose to round down (preferably when end-users are involved) or up. The real problem is that if you follow this reasoning, you unfortunately lose the symmetry between adding and removing a year:
original: February 29th, 2008
+ 1 year: March 1st, 2009 (rounding up)
- 1 year: March 1st, 2008
or by adding 4 years in several consecutive leaps:
original: February 29th, 2008
+ 2 years: February 28th, 2010 (rounding down)
+ 2 years: February 28th, 2012
Oups!
The mathematical solution to this is to simply evaluate the year duration in terms of seconds, Let's ask Wolfram about it: 3.154 × 10^7 seconds.
However, it may be quite confusing for the user.
And finally, the last solution is that whenever you make computations based on dates and duration, you save the original date away, compute the durations on their own, and then adjust the "displayed" date.
This way, you will be both mathematically correct (ie, respect symmetry and associativity) and behave intuitively for end users.
class MyTime {
...
private:
tm _origin;
tm _deviation;
};
However it is more work... so you have to decide on your scheme by yourself, depending on your application needs.
I agree about using boost::date_time, however, the solution here is quite easy.
today->tm_year++;
Although, if you happen to call localtime again, the value will be overwritten, so you should make a copy. Make today an instance instead of a pointer, and dereference the return value of localtime like this:
today = *localtime( &ltime );
You'll have to take into account certain anomalies, like incrementing a year from February 29th on a leap year.
Edit: I see you've decided to use boost::date_time after all. This makes things much simpler. Here's how you add a year:
t += boost::gregorian::years(1);
And here's how you add 14 days:
t += boost::gregorian::days(14);
Or
t += boost::gregorian::weeks(2);
Oh good grief, you C++ people :)
// compare June 15 2018 - 2017 to 2017 - 2016
struct tm y1_tm, y2_tm, y3_tm;
time_t y1716, y1817; // differences
y1_tm.tm_sec = 0; // 2016
y1_tm.tm_min = 0;
y1_tm.tm_hour = 0;
y1_tm.tm_mon = 6;
y1_tm.tm_mday = 15;
y1_tm.tm_year = 2016 - 1900;
y1_tm.tm_mday = 1;
y2_tm.tm_sec = 0; // 2017
y2_tm.tm_min = 0;
y2_tm.tm_hour = 0;
y2_tm.tm_mon = 6;
y2_tm.tm_mday = 15;
y2_tm.tm_year = 2017 - 1900;
y2_tm.tm_mday = 1;
y3_tm.tm_sec = 0; // 2018
y3_tm.tm_min = 0;
y3_tm.tm_hour = 0;
y3_tm.tm_mon = 6;
y3_tm.tm_mday = 15;
y3_tm.tm_year = 2018 - 1900;
y3_tm.tm_mday = 1;
y1716 = mktime(&y2_tm) - mktime(&y1_tm); // 2017 - 2016
y1817 = mktime(&y3_tm) - mktime(&y2_tm); // 2018 - 2017
Both subtractions yield 31536000 seconds. Add that to a time_t for 1 year.

C++ reverse number with digit adding

Hi to all thank all in advance to those who tried to answer or answer and part of this question.
Calculate the sum of the digits of the year.
Calculate the absolute value of the difference between the year and the ’reverse’ of the year.
Calculate the number of even factors of the day.
Calculate the greatest common divisor of the day, month and year.
Calculate the number of steps required to solve the Collatz problem for
the month
These are my tasks that I need to fulfill, as Engineering student this how far I went in this. In the following codes I expect something like this
19
90
0
1
0
T M B B
The answer that I get is
Please enter your birthdate (dd mm yyyy): 12 11 1981
19
8468304
Press any key to continue . . .
8468304
How to get it right I know that my equation is right or(formula, method). However this is what I know.
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
cout << "Please enter your birthdate (dd mm yyyy): ";
int day, month, year, count,rev;
int sum = 0;
cin >> day>> month >>year;
while (year!=0)
{
int count = year%10;
sum +=count;
year /= 10;
}
while(year>0)
{
rev = year%10;
year=year/10;
}
cout<<sum<<endl;
cout << rev;
system ("pause");
return 0;
}//end main
Please help!
After your first loop, while (year != 0), you don't reset the value of year, so it remains at zero and the second loop doesn't execute at all.
You need to save the value of year and use it when you start the second loop.
Just a note on organisation: I'd suggest to write a subroutine/function for every task, like
int digit_sum(int year) {
/* ... */
return sum;
}
int reverse_difference(int year) {
/* ... */
return diff;
}
and so on. This way you'll also prevent errors like modifying the year variable during the first calculation without saving the original value (which you did, as David Winant already pointed out).