//
#include <chrono>
#include <iostream>
#include <vector>
#include <tuple>
#include <cassert>
#include <cmath>
using namespace std;
void benchmark();
void benchmark_proper();
int find_third_member_of_ptt(int z, int x);
int main()
{
benchmark();
benchmark_proper();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Benchmark Code
////////////////////////////////////////////////////////////////////////////////////////////////////
class timer
{
private:
std::chrono::high_resolution_clock::time_point start_;
public:
timer()
{
reset();
}
void reset()
{
start_ = std::chrono::high_resolution_clock::now();
}
std::chrono::milliseconds elapsed() const
{
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start_);
}
friend std::ostream &operator<<(std::ostream &sout, timer const &t)
{
return sout << t.elapsed().count() << "ms";
}
};
static constexpr int max_triples = 2000;
void benchmark()
{
timer t;
t.reset();
vector<tuple<int,int,int>> ptt;
for(int z = 1;; ++z)
{
for(int x = 1; x <= z; ++x)
{
for(int y = x; y <= z; ++y)
{
if(x*x + y*y == z*z)
{
ptt.push_back(make_tuple(x,y,z));
if(ptt.size() == max_triples)
goto done;
}
}
}
}
done:
std::cout << t << '\n';
//for (const auto & triplet : ptt)
// cout << get<0>(triplet) << " " << get<1>(triplet) << " " << get <2>(triplet) << endl;
}
// -1 == not found, yes boost optional would be better choice
int find_third_member_of_ptt(int z, int x)
{
assert(z>x);
const int diff = z*z - x*x;
const double sqroot = sqrt(diff);
const int candidate1 = (int)sqroot;
const int candidate2 = (int)sqroot +1;
// next 2 checks are the same and should be in a function
if ( (candidate1 >= x) && //prevents duplicates
(z*z == x*x + candidate1*candidate1))
return candidate1;
if ((candidate2 >= x) && //prevents duplicates
(z*z == x*x + candidate2*candidate2))
return candidate2;
return -1;
}
void benchmark_proper()
{
timer t;
t.reset();
vector<tuple<int,int,int>> ptt;
for(int z = 1;; ++z)
{
for(int x = 1; x < z; ++x)
{
if (find_third_member_of_ptt(z,x) !=-1)
{
ptt.push_back(make_tuple(x,find_third_member_of_ptt(z,x),z)); // we are so fast we dont need to remember the rv of a function...
if(ptt.size() == max_triples)
goto done; // so great that we have goto in if now, goto == maintainable code, we could put it outside if but *I* know check only needs to be done if push_back occured
}
}
}
done:
std::cout << t << '\n';
//for (const auto & triplet : ptt)
// cout << get<0>(triplet) << " " << get<1>(triplet) << " " << get <2>(triplet) << endl;
}