I am trying to make a text game where there is a timer and once the game was finished before or in 60 seconds, there is a bonus points. However, I have no idea how can I get the value or the time from using the chrono without cout-ing it. I want to use the value for calculating the bonus point. i can cout the value through the .count() but I cannot get that value to use for the condition part.
here's my code for the scoring part:
void Game::score(auto start, auto end) {
int bonus = 0;
int total = 0;
string name;
box();
gotoxy(10,8); cout << "C O N G R A T U L A T I O N S";
gotoxy(15,10); cout << "You have successfully accomplished all the levels!";
gotoxy(15,11); cout << "You are now a certified C-O-N-N-E-C-T-o-r-I-s-T" << char(002) << char(001);
gotoxy(20,13); cout << "= = = = = = = = = = GAME STATS = = = = = = = = = =";
gotoxy(25,15); cout << "Time Taken: " << chrono::duration_cast<chrono::seconds>(end - start).count() << " seconds";
gotoxy(25,16); cout << "Points: " << pts << " points";
if (chrono::duration_cast<chrono::seconds>(end - start).count() <= 60) {
bonus == 5000;
} else if (chrono::duration_cast<chrono::seconds>(end - start).count() <= 90) {
bonus == 3000;
} else if (chrono::duration_cast<chrono::seconds>(end - start).count() <= 120) {
bonus == 1000;
}
gotoxy(30,17); cout << "Bonus Points (Time Elapsed): " << bonus;
total = pts + bonus;
gotoxy(25,18); cout << "Total Points: " << total << " points";
gotoxy(20,20); cout << "Enter your name: ";
cin >> name;
scoreB.open("scoreboard.txt",ios::app);
scoreB << name << "\t" << total << "\n";
scoreB.close();
}
You should really use the chrono literals for comparing durations. See example here:
#include <chrono>
#include <iostream>
#include <thread>
using Clock = std::chrono::system_clock;
void compareTimes(std::chrono::time_point<Clock> startTime,
std::chrono::time_point<Clock> finishTime) {
using namespace std::chrono_literals;
std::chrono::duration<float> elapsed = finishTime - startTime;
std::cout << "elapsed = " << elapsed.count() << "\n";
if (elapsed > 10ms) {
std::cout << "over 10ms\n";
}
if (elapsed < 60s) {
std::cout << "under 60s\n";
}
}
int main() {
using namespace std::chrono_literals;
auto startTime = Clock::now();
std::this_thread::sleep_for(20ms);
auto finishTime = Clock::now();
compareTimes(startTime, finishTime);
return 0;
}
Demo: https://godbolt.org/z/hqv58acoY
Related
I'm trying to write a simple single header benchmarker and I understand that std::clock will give me the time that a process (thread) is in actual use.
So, given the following simplified program:
nt main() {
using namespace std::literals::chrono_literals;
auto start_cpu = std::clock();
auto start_wall = std::chrono::high_resolution_clock::now();
// clobber();
std::this_thread::sleep_for(1s);
// clobber();
auto finish_cpu = std::clock();
auto finish_wall = std::chrono::high_resolution_clock::now();
std::cerr << "cpu: "
<< start_cpu << " " << finish_cpu << " "
<< (finish_cpu - start_cpu) / (double)CLOCKS_PER_SEC << " s" << std::endl;
std::cerr << "wall: "
// << FormatTime(start_wall) << " " << FormatTime(finish_wall) << " "
<< (finish_wall - start_wall) / 1.0s << " s" << std::endl;
return 0;
}
Demo
We get the following output:
cpu: 4820 4839 1.9e-05 s
wall: 1.00007 s
I just want to clarify that the cpu time is the time that it executes the code that is not actually the sleep_for code as that is actually done by the kernel which std::clock doesn't track. So to confirm, I changed what I was timing:
int main() {
using namespace std::literals::chrono_literals;
int value = 0;
auto start_cpu = std::clock();
auto start_wall = std::chrono::high_resolution_clock::now();
// clobber();
for (int i = 0; i < 1000000; ++i) {
srand(value);
value = rand();
}
// clobber();
std::cout << "value = " << value << std::endl;
auto finish_cpu = std::clock();
auto finish_wall = std::chrono::high_resolution_clock::now();
std::cerr << "cpu: "
<< start_cpu << " " << finish_cpu << " "
<< (finish_cpu - start_cpu) / (double)CLOCKS_PER_SEC << " s" << std::endl;
std::cerr << "wall: "
// << FormatTime(start_wall) << " " << FormatTime(finish_wall) << " "
<< (finish_wall - start_wall) / 1.0s << " s" << std::endl;
return 0;
}
Demo
This gave me an output of:
cpu: 4949 1398224 1.39328 s
wall: 2.39141 s
value = 354531795
So far, so good. I then tried this on my windows box running MSYS2's g++ compiler. The output for the last program gave me:
value = 0
cpu: 15 15 0 s
wall: 0.0080039 s
std::clock() is always outputting 15? Is the compiler implementation of std::clock() broken?
Seems that I assumed that CLOCKS_PER_SEC would be the same. However, on the MSYS2 compiler, it was 1000x less then on godbolt.org.
I am attemtping to access and pop the front element from a queue in C++, but the line
tuple<int, string, future<string>> post = posterVerificationQueue.front();
is underlined in red and gives the error:
function "std::tuple<_This, _Rest...>::tuple(const std::tuple<_This,
_Rest...> &) [with _This=int, _Rest=<std::string, std::futurestd::string>]" (declared at line 320 of "C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\tuple") cannot
be referenced -- it is a deleted function
I imagine it is an issue with me using a future within a tuple, but not too sure. Here is my code:
#include <iostream>
#include <ctime>
#include <chrono>
#include <thread>
#include <future>
#include <queue>
#include <mutex>
#include <tuple>
#include <map>
#include "TCPClient.h"
#include "ThreadPool.h"
#include "RequestGenerator.h"
#include "ResponseVerifier.h"
#include "Storage.h"
#define DEFAULT_PORT 12345
void readRequest(string serverIp, int threadIndex, double timeDurationSecs);
void postRequest(string serverIp, int threadIndex, double timeDurationSecs);
int readRequests = 0;
int postRequests = 0;
mutex mLock;
map<int, tuple<double, int>> posterThreadMap;
queue<tuple<int, string, future<string>>> posterVerificationQueue;
map<int, tuple<double, int>> readerThreadMap;
Storage* db = new Storage();
RequestGenerator* requestGenerator = new RequestGenerator();
int main(int argc, char **argv)
{
// Default parameters
unsigned int posterCount = 5;
unsigned int readerCount = 0;
double timeDurationSecs = 10;
bool throttle = false;
string serverIp = "127.0.0.1";
// Validate the parameters
if (argc != 6) {
std::cout << "\nUsage (required parameters): server_IP number_of_poster_threads number_of_reader_threads time_duration throttle(0|1)\n\n";
std::cout << "server_IP - IP of the server\n";
std::cout << "number_of_poster_threads - number of threads performing POST operations\n";
std::cout << "number_of_reader_threads - number of threads performing READ operations\n";
std::cout << "time_duration - duration of test execution in seconds\n";
std::cout << "throttle(0|1) - 0: do not throttle message speed\n";
std::cout << "\t\t1: throttle message speed\n\n";
std::cout << "\nDefault Parameters:\n";
std::cout << "\tserver_IP - " << serverIp << "\n";
std::cout << "\tnumber_of_poster_threads - " << posterCount << "\n";
std::cout << "\tnumber_of_reader_threads - " << readerCount << "\n";
std::cout << "\ttime_duration - " << timeDurationSecs << "s\n";
std::cout << "\tthrottle - " << (throttle ? "true" : "false") << "\n\n";
std::cout << "Enter dev mode using default paramaters?\n";
system("pause");
}
else
{
serverIp = argv[1];
posterCount = (int)argv[2];
readerCount = (int)argv[3];
timeDurationSecs = (int)argv[4];
throttle = (int)argv[5];
}
cout << "\nStarting throughput test...\n";
ThreadPool posterPool(posterCount);
vector<future<void>> posterFutures;
vector<tuple<string, int, int>> incorrectPostResponses;
double posterTotalTime = 0.0; // The total time in seconds that all poster threads took to run
ThreadPool readerPool(readerCount);
vector<future<void>> readerFutures;
double readerTotalTime = 0.0; // The total time in seconds that all reader threads took to run
for (int i = 0; i < posterCount; i++)
posterFutures.push_back(posterPool.enqueue(postRequest, serverIp, i, timeDurationSecs));
for (int i = 0; i < readerCount; i++)
readerFutures.push_back(readerPool.enqueue(readRequest, serverIp, i, timeDurationSecs));
for (int i = 0; i < posterFutures.size(); i++)
posterFutures[i].wait();
for (int i = 0; i < readerFutures.size(); i++)
readerFutures[i].wait();
for (int i = 0; i < posterThreadMap.size(); i++)
{
double posterRequestsPerSecond = get<1>(posterThreadMap[i]);
double threadRunTime = get<0>(posterThreadMap[i]);
posterTotalTime += threadRunTime;
std::cout << "\nPoster thread " << i << " (ran for " << threadRunTime << "s) - Average post requests per second: " << posterRequestsPerSecond << "\n";
}
// Should verification be optional?
while (!posterVerificationQueue.empty())
{
tuple<int, string, future<string>> post = posterVerificationQueue.front();
posterVerificationQueue.pop();
int postIndex = get<0>(post);
string request = get<1>(post);
string response = get<2>(post).get();
tuple<bool, int, int> postVerification = db->addPosterValue(postIndex, request, response);
bool isValid = get<0>(postVerification);
if (!isValid)
{
int correctResponse = get<1>(postVerification);
int actualResponse = get<2>(postVerification);
incorrectPostResponses.push_back(make_tuple(request, correctResponse, actualResponse));
}
}
cout << "\nTotal poster runtime: " << posterTotalTime << "s" << "\n";
cout << "\nTotal post requests: " << postRequests << "\n";
cout << "\nAverage post requests per second per thread: " << postRequests / posterTotalTime << "\n";
cout << "\nIncorrect responses: " << incorrectPostResponses.size() << "\n";
for (int i = 0; i < incorrectPostResponses.size(); i++)
{
tuple<string, int, int> incorrectResponse = incorrectPostResponses[i];
string request = get<0>(incorrectResponse);
int correctResponse = get<1>(incorrectResponse);
int actualResponse = get<2>(incorrectResponse);
cout << "Incorrect response #" << i + 1 << "\n";
cout << "Request: " << request << "\n";
cout << "Expected response: " << correctResponse << "\n";
cout << "Actual response: " << actualResponse << "\n\n";
}
// TODO: Implement the block above for reader threads
delete db;
delete requestGenerator;
system("pause");
return 0;
}
string sendRequest(TCPClient client, string request)
{
return client.send(request);
}
void postRequest(string serverIp, int threadIndex, double timeDurationSecs)
{
TCPClient client(serverIp, DEFAULT_PORT);
client.OpenConnection();
int threadPostCount = 0;
double timeSpan;
chrono::high_resolution_clock::time_point endTime;
chrono::high_resolution_clock::time_point startTime = chrono::high_resolution_clock::now();
do
{
/*
Could limit with
if (!throttle || (throttle && threadPostCount < (timeDurationSecs * 1000)))
{}
*/
string request = requestGenerator->generateWriteRequest();
mLock.lock();
future<string> responseFut = async(launch::async, sendRequest, client, request);
posterVerificationQueue.push(make_tuple(postRequests, request, move(responseFut)));
postRequests++;
mLock.unlock();
threadPostCount++;
endTime = chrono::high_resolution_clock::now();
timeSpan = chrono::duration_cast<chrono::duration<double>>(endTime - startTime).count();
} while (timeSpan < timeDurationSecs);
double totalRunTime = (endTime - startTime).count();
double posterRequestsPerSecond = threadPostCount / timeSpan;
tuple<double, double> returnValues = make_tuple(timeSpan, posterRequestsPerSecond);
mLock.lock();
postRequests += threadPostCount;
posterThreadMap[threadIndex] = returnValues;
mLock.unlock();
client.CloseConnection();
}
void readRequest(string serverIp, int threadIndex, double timeDurationSecs)
{
//return 0.0;
}
std::tuple<_This, _Rest...>::tuple(const std::tuple<_This, _Rest...> &)
...
cannot be referenced -- it is a deleted function
Well, that's the tuple copy constructor, right?
I imagine it is an issue with me using a future within a tuple, but not too sure.
Let's check the documentation for the constructors of std::future ...
future( const future& other ) = delete;
std::future is not CopyConstructible.
So I'd say your imagination was correct. You can't copy the tuple, because it can't copy one of its members.
You can use std::move to move construct from the queue element, but remember it would be a problem if you didn't pop the front immediately after (in the code shown, you do this, so it's fine).
Here is our code for the task we are almost finishing just the last part we are stuck at
"Fastest: 3 trips (1 Van, 3 Mini-lorry, $645) "
we are not sure how to display the values in the bracket we only able to display 3 trips.
Is there a way to also display the values in the bracket stated as well?
we use
int min = *min_element(vTrips.begin(), vTrips.end());
cout << "Fastest: " << min << " trips" << endl;
but this only display the 3 trips.
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include<algorithm>
using namespace std;
class CTS //cargo transport system
{
int i;
int cargo, lorryprice, vanprice, lorrysize, vansize, allOps;
public:
void set_cargo(int);
void set_lorryprice(int);
void set_vanprice(int);
void set_lorrysize(int);
void set_vansize(int);
};
void CTS::set_cargo(int total_cargo) {
cargo = total_cargo;
}
void CTS::set_lorryprice(int lorryP) {
lorryprice = lorryP;
}
void CTS::set_vanprice(int vanP) {
vanprice = vanP;
}
void CTS::set_lorrysize(int lorryS) {
lorrysize = lorryS;
}
void CTS::set_vansize(int vanS)
{
vansize = vanS;
}
int main()
{
int cargo, lorryprice, vanprice, lorrysize, vansize, options, i, no_lorry, no_van, cost, trips;
ifstream infile;
infile.open("size.txt");
if (infile.is_open()) {
infile >> cargo;
infile >> lorryprice;
infile >> vanprice;
infile >> lorrysize;
infile >> vansize;
}
CTS run;
run.set_cargo(cargo);
run.set_lorryprice(lorryprice);
run.set_vanprice(vanprice);
run.set_lorrysize(lorrysize);
run.set_vansize(vansize);
infile.close();
options = (cargo / lorrysize) + 1;
no_lorry = (cargo / lorrysize);
no_van = (cargo / vansize) + 3;
if (cargo % lorrysize == 0) {
no_van = -3;
}
if (cargo % lorrysize != 0) {
no_van = ((cargo % lorrysize) / 10) - 3;
}
/*it = numbervan.begin();
for (auto ir = numbervan.rbegin(); ir != numbervan.rend(); ++ir) {
cout << *ir << endl;
}*/
vector<int> vCost, vVan, vTrips, vLorry;
vector <int>::iterator it;
for (i = 1; i < options + 1; i++)
{
int numberlorry = no_lorry;
cout << "Option " << i << ":" << endl;
cout << "Number of Mini-Lorries : " << no_lorry-- << endl;
if (no_van >= -3) {
no_van += 3;
}
cout << "Number of Vans : " << no_van << endl;
int numbervan = no_van;
if (numberlorry > numbervan) {
trips = numberlorry;
}
else {
trips = numbervan;
}
cout << "Trips Needed : " << trips << endl;
cost = (numberlorry * lorryprice) + (no_van * vanprice);
cout << "Total Cost : $" << cost << endl;
vCost.push_back(cost);
vLorry.push_back(numberlorry);
vVan.push_back(numbervan);
vTrips.push_back(trips);
}
int counter = vCost.size() - 1;
//std::vector<int>::reverse_iterator ir = vCost.rbegin();
for (i = 1; i < 4; i++) {
//cout << "Lowest #" << i << ": "<<cost<<endl;
cout << "Lowest #" << i << ": $" << vCost[counter] << "(" << vVan[counter] << " Vans, " << vLorry[counter] << " Mini-Lorry, " << vTrips[counter] << " Trips)" << endl;
counter--;
}
int min = *min_element(vTrips.begin(), vTrips.end()); // this line of code we figured out how to
cout << "Fastest: " << min << " trips" << endl; //display the number of trips using algorithm
return 0;
}
Your design is awkward; you create an instance of CTS run; and never use it.
Assuming that you do your calculations right, you need to know at what index you found min. If you store the iterator returned by min_element(), you can get an index by subtracting vTrips.begin() from it. Then the corresponding elements in your vCost, vLorry and vVan vectors will contain the data you want.
However, it would be easier if you define a struct containing your pre-calculated values, and push that into some vector. In that case, all related data is kept together.
For this car wash simulation, your program reads in the car arrival time through an input file. The total wash time for a car is 3 minutes. Another car can not go into the wash while a car is being washed which will increase the waiting time. If a car departs at minute 3 the next car needs to go in at minute 4 if it has already arrived.
I have already tried reading in the file all at once and then creating another loop but that has not worked. I have tried many things, I think I am only having a problem with how to loop the program.
#include <iostream>
#include <cassert>
#include <fstream>
#include <queue>
#include <cstdlib>
using namespace std;
class averager {
private:
int cnt;
int sum;
public:
averager(){
cnt=0;
sum=0;
}
void plus_next_number(int value)
{
cnt++;
sum+=value;
}
double average_time()
{
assert(cnt>0);
return (sum/cnt);
}
int how_many_cars()
{
return cnt;
}
};
class Washmachine {
private:
int time_for_wash;
int time_left;
public:
Washmachine(int n) {
time_for_wash = n;
time_left = 0;
}
bool is_busy() {
return (time_left > 0);
}
void startWashing() {
if(!is_busy()) {
time_left = time_for_wash;
}
}
void one_second(){
if(is_busy()) {
--time_left;
}
}
};
int main() {
queue<int> waitQueue;
int carArrival;
averager cal;
ifstream infile;
ofstream arrivalrec;
arrivalrec.open("arrival_time.txt");
arrivalrec << "Car Number " << "Arrival Time " << "Car Wash Start Time " << "Departure Time "
<< "Wait Time "
<< "Total Time " << endl
<< endl;
int maxWaitTime; // maxWaitTime initially 0:00
int totalWaitTime; // total time customers wait
int endTime = 540; // times for the simulation
int totalServiceTime;
int startTime;
int carNum = 0; // number of cars washed in study
int washTime = 3; // fixed time for a wash in minutes
int DeptTime;
int TotalTime;
int timeleft=0;
int waitTime;
int temp;
int sw;
Washmachine carwashing(washTime);
infile.open("input.txt");
for (int startTime=0;startTime<=endTime;startTime++){
infile>>temp;
waitQueue.push(temp);
if((!carwashing.is_busy())&&(!waitQueue.empty())) {
carArrival=waitQueue.front();
waitQueue.pop();
waitTime=temp-carArrival;
cal.plus_next_number(temp-carArrival);
carwashing.startWashing();
}
carwashing.one_second();
if (maxWaitTime<waitTime)
maxWaitTime=waitTime;
// add waiting time for customer to totalWaitTime.
totalWaitTime+=waitTime;
totalServiceTime+=washTime;
startTime=temp+waitTime;
TotalTime=washTime+waitTime;
DeptTime=startTime +washTime;
// increment the number of customers served
carNum++;
// set washAvailable to false since equipment back in service
// output the summary data for the simulation include number of cars
// washed, average customer waiting time and pct of time wash operates
arrivalrec << carNum << " " << temp << " " <<startTime
<< " " << DeptTime << " " <<
waitTime << " " << TotalTime << endl
<< endl << endl;
}
arrivalrec << "Maximum customer waiting time for a car wash is "
<< "14 minutes" << endl;
arrivalrec << "Percentage of time car wash operates is 57 "
//<< ((totalServiceTime / endTime) * 100.0)
<< '%' << endl;
arrivalrec << "Number of customers remaining at " << endTime
<< " is 8"<<endl; //<< waitQueue.size() << endl;
arrivalrec<<"\nCars washed were: "<<carNum<<endl;
arrivalrec<<"\nThe average waiting time is: "<<cal.average_time()<<endl;
int car_denied=0;
while(!waitQueue.empty())
{
waitQueue.pop();
car_denied++;
}
arrivalrec<<"\nThe number of denied cars is: 2 "<<endl;
arrivalrec<<endl;
return 0;
}
Car Arrival 0 car start 0 car depart 3 wait time 0 total time 3
3 4 7 1 4
10 10 13 0 3
11 14 17 3 6
Please try the following loop for the main function of your Car washing simulation.
Instead of looping over startTime, the loop uses the simulation runTime. All events like putting a car to the queue, starting and documenting the car washing process as well as counting waitTime are done by conditions:
infile.open("input.txt");
infile >> temp;
carNum = 1;
for (runTime=1;runTime<=endTime;runTime++){
if (runTime == temp) {
waitQueue.push(temp);
infile >> temp;
}
if((!carwashing.is_busy())&&(!waitQueue.empty())) {
carArrival=waitQueue.front();
waitQueue.pop();
startTime = runTime;
waitTime=startTime-carArrival;
totalWaitTime = waitTime;
TotalTime = washTime + waitTime;
cal.plus_next_number(startTime-carArrival);
carwashing.startWashing();
}
else
{
waitTime++;
}
if (carwashing.is_busy())
carwashing.one_second();
if ((!carwashing.is_busy())&&(startTime >= DeptTime)) {
DeptTime = startTime + washTime;
totalServiceTime += washTime;
arrivalrec << carNum << " " << carArrival << " " << startTime
<< " " << DeptTime << " " <<
totalWaitTime << " " << TotalTime << endl
<< endl << endl;
carNum++;
}
}
Please note that the file reading of the first car is done outside of the loop.
I also added the runTime variable and some initialization to your declaration:
queue<int> waitQueue;
int carArrival = 0;
averager cal;
ifstream infile;
ofstream arrivalrec;
arrivalrec.open("arrival_time.txt");
arrivalrec << "Car Number " << "Arrival Time " << "Car Wash Start Time " << "Departure Time "
<< "Wait Time "
<< "Total Time " << endl
<< endl;
int maxWaitTime = 0; // maxWaitTime initially 0:00
int totalWaitTime = 0; // total time customers wait
int endTime = 75; // times for the simulation
int totalServiceTime = 0;
int startTime = 0;
int carNum = 0; // number of cars washed in study
int washTime = 3; // fixed time for a wash in minutes
int DeptTime = 0;
int TotalTime = 0;
int timeleft=0;
int waitTime=0;
int temp;
int sw;
int runTime;
Washmachine carwashing(washTime);
I've taken the desired output from your other post:
Hope it helps you?
I am testing some algorithms and timing them. I would like to know how to abort the function while its running if it runs for longer than 60 seconds. Here's what I'm working with:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <ctime>
#include <chrono>
#include <cstdlib>
#include <random>
#include <algorithm>
using namespace std;
bool isUnique(const vector<int>& arr, int start, int end) {
if (start >= end) return true;
if (!isUnique(arr, start, end - 1))
return false;
if (!isUnique(arr, start + 1, end))
return false;
return (arr[start] != arr[end]);
}
bool isUniqueLoop(const vector<int>& arr, int start, int end) {
if (start >= end) return true;
for (int i = start; i < end; i++)
for (int j = i + 1; j <= end; j++)
if (arr[i] == arr[j])return false;
return true;
}
bool isUniqueSort(const vector<int>& arr, int start, int end) {
if (start <= end) return true;
vector<int> buf(arr);
sort(buf.begin() + start, buf.begin() + end);
for (int i = start; i < end; i++)
if (buf[i] == buf[i + 1]) return false;
return true;
}
int main() {
int max = 0;
cout << "Enter a number for the Max range: ";
cin >> max;
default_random_engine randGen(time(0));
uniform_int_distribution<int> randNum(0, max);
int i;
int j;
int n = randNum(randGen);
int m = n;
vector<int> myVect;
for (i = 0; i <= m; i++) {
myVect.push_back(randNum(randGen));
//cout << myVect[i] << endl;
}
cout << "Recursive Algorithm Test... " << endl;
cout << endl;
// recursive algorithm
clock_t start = clock();
isUnique(myVect, 0, n);
if (isUnique(myVect, 0, n) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end = clock();
double time = (double)(end - start) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU Time used for this algorithm: " << time << " ms" << endl;
if (time > 60000) {
cout << "This function takes too long! " << endl;
}
cout << "------------------------------------" << endl;
cout << "Iterative Algorithm Test... " << endl;
cout << endl;
// iterative algorithm
clock_t start2 = clock();
isUniqueLoop(myVect, 0, n);
if (isUniqueLoop(myVect, 0, n) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end2 = clock();
double time2 = (double)(end2 - start2) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time2 << " ms. " << endl;
if (time2 > 60000) {
cout << "This function takes too long! " << endl;
}
cout << "------------------------------------" << endl;
cout << "Sort Algorithm Test... " << endl;
cout << endl;
// sort algorithm
clock_t start3 = clock();
isUniqueSort(myVect, 0, n);
if (isUniqueSort(myVect, 0, n) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique " << endl;
}
clock_t end3 = clock();
double time3 = (double)(end3 - start3) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time3 << " ms. " << endl;
if (time3 > 60000) {
cout << "This function takes too long! " << endl;
}
cout << endl;
system("pause");
return 0;
}
everything works fine except the fact that I want it to quit the function isUnique(myVect, 0, m) if it lasts longer than 60 seconds....Any suggestions?
When you have an exceptional circumstance (like a timeout) you can throw an exception. In your case what kind of exceptions is up to you. Exceptions work well when you want to exit a many levels deep call tree without having to check every function individually for an exit return code. In the example below I am throwing a string as an exception:
Edit
To prevent doing the time calculations way too often here is an attempt to limit how often they are done. This is by no means scientific, but on my box it gives a reasonable result. If you have a better way let me know.
#include <iostream>
#include <vector>
#include <ctime>
#include <chrono>
#include <cstdlib>
#include <random>
#include <algorithm>
bool isUnique(const std::vector<int>& arr, int start, int end, clock_t clock_start,
unsigned long & iterations, unsigned long timecheck) {
if (++iterations > timecheck) {
iterations = 0;
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) * 1000.0 / CLOCKS_PER_SEC;
if (time > 60000) throw "This function takes too long!";
else std::cout << time << " ms elapsed..." << std::endl;
}
if (start >= end) return true;
if (!isUnique(arr, start, end - 1, clock_start, iterations, timecheck))
return false;
if (!isUnique(arr, start + 1, end, clock_start, iterations, timecheck))
return false;
return (arr[start] != arr[end]);
}
bool isUniqueLoop(const std::vector<int>& arr, int start, int end, clock_t clock_start,
unsigned long & iterations, unsigned long timecheck) {
if (start >= end) return true;
for (int i = start; i < end; i++) {
for (int j = i + 1; j <= end; j++) {
if (++iterations > timecheck) {
iterations = 0;
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) * 1000.0 / CLOCKS_PER_SEC;
if (time > 60000) throw "This function takes too long!";
else std::cout << time << " ms elapsed..." << std::endl;
}
if (arr[i] == arr[j])return false;
}
}
return true;
}
bool isUniqueSort(const std::vector<int>& arr, int start, int end, clock_t clock_start,
unsigned long & iterations, unsigned long timecheck) {
if (start <= end) return true;
std::vector<int> buf(arr);
sort(buf.begin() + start, buf.begin() + end);
for (int i = start; i < end; i++) {
if (++iterations > timecheck) {
iterations = 0;
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) * 1000.0 / CLOCKS_PER_SEC;
if (time > 60000) throw "This function takes too long!";
else std::cout << time << " ms elapsed..." << std::endl;
}
if (buf[i] == buf[i + 1]) return false;
}
return true;
}
unsigned long calculate_timecheck() {
// since we want to limit the functions to 60 seconds we need to check how
// long they have been running but we don't want to do that all the time
// so we should only check so often - here is an attemopt to figure out how often
unsigned long upperlimit = 1;
volatile unsigned long i;
clock_t start, current;
double time;
do {
if (upperlimit > ULONG_MAX/2) return ULONG_MAX-1;
upperlimit *= 2;
start = clock();
for (i = 0; i < upperlimit*100000; i++);
current = clock();
time = (double)(current - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << upperlimit*100000 << " iterations took " << time << " ms." << std::endl;
} while (time<500);
return upperlimit*100000;
}
int main() {
int max = 0;
std::cout << "Enter a number for the Max range: ";
std::cin >> max;
std::default_random_engine randGen(time(0));
std::uniform_int_distribution<int> randNum(0, max);
int n = randNum(randGen);
int m = n;
std::vector<int> myVect;
for (int i = 0; i <= m; i++) {
myVect.push_back(randNum(randGen));
//std::cout << myVect[i] << std::endl;
}
std::cout << "Calculating timeout... " << std::endl;
std::cout << std::endl;
unsigned long timecheck = calculate_timecheck();
std::cout << "Will check for timeout every " << timecheck << " iterations..." << std::endl;
std::cout << std::endl;
std::cout << "------------------------------------" << std::endl;
// recursive algorithm
try {
std::cout << "Recursive Algorithm Test... " << std::endl;
std::cout << std::endl;
clock_t start = clock();
unsigned long iterations = 0;
// isUnique(myVect, 0, n, start, iterations, timecheck);
if (isUnique(myVect, 0, n, start, iterations, timecheck) == true) {
std::cout << "The Vector is Unique! " << std::endl;
}
else {
std::cout << "The Vector is not Unique! " << std::endl;
}
clock_t end = clock();
double time = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << "CPU Time used for this algorithm: " << time << " ms." << std::endl;
} catch (const char *err) {
std::cout << err << std::endl;
}
std::cout << "------------------------------------" << std::endl;
// iterative algorithm
try {
std::cout << "Iterative Algorithm Test... " << std::endl;
std::cout << std::endl;
clock_t start = clock();
unsigned long iterations = 0;
// isUniqueLoop(myVect, 0, n, start, iterations, timecheck);
if (isUniqueLoop(myVect, 0, n, start, iterations, timecheck) == true) {
std::cout << "The Vector is Unique! " << std::endl;
}
else {
std::cout << "The Vector is not Unique! " << std::endl;
}
clock_t end = clock();
double time = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << "CPU time used for this algorithm: " << time << " ms." << std::endl;
} catch (const char *err) {
std::cout << err << std::endl;
}
std::cout << "------------------------------------" << std::endl;
// sort algorithm
try {
std::cout << "Sort Algorithm Test... " << std::endl;
std::cout << std::endl;
clock_t start = clock();
unsigned long iterations = 0;
// isUniqueSort(myVect, 0, n, start, iterations, timecheck);
if (isUniqueSort(myVect, 0, n, start, iterations, timecheck) == true) {
std::cout << "The Vector is Unique! " << std::endl;
}
else {
std::cout << "The Vector is not Unique " << std::endl;
}
clock_t end = clock();
double time = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;
std::cout << "CPU time used for this algorithm: " << time << " ms." << std::endl;
} catch (const char *err) {
std::cout << err << std::endl;
}
std::cout << std::endl;
system("pause");
return 0;
}
Original:
#include <iostream>
#include <vector>
#include <ctime>
#include <chrono>
#include <cstdlib>
#include <random>
#include <algorithm>
using namespace std;
bool isUnique(const vector<int>& arr, int start, int end, clock_t clock_start) {
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) / CLOCKS_PER_SEC * 1000.0;
if (time > 60000) throw "This function takes too long!";
if (start >= end) return true;
if (!isUnique(arr, start, end - 1, clock_start))
return false;
if (!isUnique(arr, start + 1, end, clock_start))
return false;
return (arr[start] != arr[end]);
}
bool isUniqueLoop(const vector<int>& arr, int start, int end, clock_t clock_start) {
if (start >= end) return true;
for (int i = start; i < end; i++) {
for (int j = i + 1; j <= end; j++) {
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) / CLOCKS_PER_SEC * 1000.0;
if (time > 60000) throw "This function takes too long!";
if (arr[i] == arr[j])return false;
}
}
return true;
}
bool isUniqueSort(const vector<int>& arr, int start, int end, clock_t clock_start) {
if (start <= end) return true;
vector<int> buf(arr);
sort(buf.begin() + start, buf.begin() + end);
for (int i = start; i < end; i++) {
clock_t clock_current = clock();
double time = (double)(clock_current - clock_start) / CLOCKS_PER_SEC * 1000.0;
if (time > 60000) throw "This function takes too long!";
if (buf[i] == buf[i + 1]) return false;
}
return true;
}
int main() {
int max = 0;
cout << "Enter a number for the Max range: ";
cin >> max;
default_random_engine randGen(time(0));
uniform_int_distribution<int> randNum(0, max);
int i;
int j;
int n = randNum(randGen);
int m = n;
vector<int> myVect;
for (i = 0; i <= m; i++) {
myVect.push_back(randNum(randGen));
//cout << myVect[i] << endl;
}
try {
cout << "Recursive Algorithm Test... " << endl;
cout << endl;
// recursive algorithm
clock_t start = clock();
isUnique(myVect, 0, n, start);
if (isUnique(myVect, 0, n, start) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end = clock();
double time = (double)(end - start) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU Time used for this algorithm: " << time << " ms" << endl;
} catch (const char *err) {
cout << err << endl;
}
cout << "------------------------------------" << endl;
try {
cout << "Iterative Algorithm Test... " << endl;
cout << endl;
// iterative algorithm
clock_t start2 = clock();
isUniqueLoop(myVect, 0, n, start2);
if (isUniqueLoop(myVect, 0, n, start2) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique! " << endl;
}
clock_t end2 = clock();
double time2 = (double)(end2 - start2) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time2 << " ms. " << endl;
} catch (const char *err) {
cout << err << endl;
}
cout << "------------------------------------" << endl;
try {
cout << "Sort Algorithm Test... " << endl;
cout << endl;
// sort algorithm
clock_t start3 = clock();
isUniqueSort(myVect, 0, n, start3);
if (isUniqueSort(myVect, 0, n, start3) == true) {
cout << "The Vector is Unique! " << endl;
}
else {
cout << "The Vector is not Unique " << endl;
}
clock_t end3 = clock();
double time3 = (double)(end3 - start3) / CLOCKS_PER_SEC * 1000.0;
cout << "CPU time used for this algorithm: " << time3 << " ms. " << endl;
} catch (const char *err) {
cout << err << endl;
}
cout << endl;
system("pause");
return 0;
}