Last active
September 24, 2019 06:42
-
-
Save NaikSoftware/f9cf4e284794c9cdf3059fc1484071b6 to your computer and use it in GitHub Desktop.
Working Days Lab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 | |
15.01. 17:00 | |
16.01. 12:00 | |
11.02. 14:00 | |
30.01. 10:00 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdlib> | |
#include <string> | |
#include <fstream> | |
#include <iomanip> | |
#include <chrono> | |
using namespace std; | |
typedef chrono::time_point<chrono::system_clock> time_point; | |
const char *INPUT_FILENAME = "./INPUT.TXT"; // For Windows OS maybe you need to remove leading './' | |
const char *OUTPUT_FILENAME = "./OUTPUT.TXT"; // For Windows OS maybe you need to remove leading './' | |
const int DAY_START = 10; | |
const int DAY_END = 18; | |
chrono::minutes get_work_time(time_point &t1, time_point &t2); | |
/** | |
* You must place input file to run directory. | |
* Output will be placed in the same folder. | |
* | |
* Compiler: GCC C++14, Linux OS | |
*/ | |
int main() { | |
ifstream input(INPUT_FILENAME); | |
// Read count | |
string line; | |
getline(input, line); | |
int point_count = stoi(line); | |
cout << "Time points:" << point_count << endl; | |
// Read all time points to dynamic array | |
auto time_points = new time_point[point_count]; | |
tm time_buffer = {}; | |
time_t timer = time(nullptr); // Now time | |
time_buffer.tm_year = localtime(&timer)->tm_year; // Set current 2019 year (not leap) to buffer | |
for (int i = 0; i < point_count; ++i) { | |
if (getline(input, line)) { | |
istringstream iss(line); | |
iss >> get_time(&time_buffer, "%d.%m. %H:%M"); | |
cout << "Read point " << put_time(&time_buffer, "%c") << endl; | |
time_points[i] = chrono::system_clock::from_time_t(mktime(&time_buffer)); | |
} else { | |
exit(EXIT_FAILURE); // Something went wrong | |
} | |
} | |
// Sort time points from early to late | |
qsort(time_points, point_count, sizeof(*time_points), [](const void *a, const void *b) { | |
// Closure (anonymous function) with custom sorting logic | |
time_point arg1 = *static_cast<const time_point *>(a); | |
time_point arg2 = *static_cast<const time_point *>(b); | |
return arg1.time_since_epoch().count() > arg2.time_since_epoch().count() ? 1 : -1; // 1 - a > b, -1 b > a, 0 = objects are equals | |
}); | |
// Concatenate all work periods | |
chrono::minutes overall(0); | |
for (int i = 0; i < point_count; i += 2) { | |
chrono::minutes work_time = get_work_time(time_points[i], time_points[i + 1]); | |
overall += work_time; | |
} | |
delete[] time_points; // Clear dynamic memory after use | |
// Print results | |
long minutes = overall.count(); | |
long hourMinutes = minutes % 60; | |
cout << "Overall: " << minutes / 60 << ":"; | |
if (hourMinutes < 10) cout << "0" << hourMinutes << endl; | |
else cout << hourMinutes << endl; | |
// Write results to file | |
remove(OUTPUT_FILENAME); | |
ofstream output(OUTPUT_FILENAME); | |
output << minutes / 60 << ":"; | |
if (hourMinutes < 10) output << "0" << hourMinutes; | |
else output << hourMinutes; | |
output.close(); | |
return EXIT_SUCCESS; | |
} | |
chrono::minutes get_work_time(time_point &t1, time_point &t2) { | |
time_t tt = chrono::system_clock::to_time_t(t1); | |
tm start = *localtime(&tt); | |
tt = chrono::system_clock::to_time_t(t2); | |
tm end = *localtime(&tt); | |
long days = end.tm_yday - start.tm_yday + 1; | |
cout << "days in period " << days << endl; | |
cout << "from " << put_time(&start, "%c") << " to " << put_time(&end, "%c") << endl; | |
if (days == 1) { | |
auto result = chrono::duration_cast<chrono::minutes>(t2 - t1 + chrono::minutes(1)); | |
cout << "add period for single working day" << result.count() / 60 << ":" << result.count() % 60 << endl; | |
return result; | |
} else { | |
chrono::minutes result = chrono::minutes(1); | |
if (days > 2) { | |
cout << "add full working days " << (days - 2) * 8 << ":00" << endl; | |
result += chrono::hours(8 * (days - 2)); // Add full working days if existing | |
} | |
result += chrono::minutes(DAY_END * 60 - start.tm_hour * 60 - start.tm_min); // Add first day of period; | |
result += chrono::minutes(end.tm_hour * 60 + end.tm_min - DAY_START * 60); // Add last day of period | |
return result; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103:02 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment