Skip to content

Instantly share code, notes, and snippets.

Created March 9, 2017 20:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/e12bdda4299814180cafffa341fdf9ca to your computer and use it in GitHub Desktop.
Save anonymous/e12bdda4299814180cafffa341fdf9ca to your computer and use it in GitHub Desktop.
The Pi Day Challenge 02/2017
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <utility>
constexpr double PI = 3.14159265359;
template<typename T>
class RandomPointGenerator
{
public:
RandomPointGenerator(std::mt19937& engine, T inf, T sup) : m_engine(engine), m_dist(inf, sup) { }
std::pair<T, T> operator()()
{
return std::make_pair(m_dist(m_engine), m_dist(m_engine));
}
private:
std::mt19937& m_engine;
std::uniform_int_distribution<T> m_dist;
};
template<typename T>
std::vector<std::pair<T, T>> generateListOfPoints(unsigned long count, RandomPointGenerator<T> gen)
{
std::vector<std::pair<T, T>> points;
points.reserve(count);
std::generate_n(std::back_inserter(points), count, gen);
return points;
}
auto inCircle(long radius)
{
return [&radius](const auto& p) {
long x = std::get<0>(p);
long y = std::get<1>(p);
return x * x + y * y < radius * radius;
};
}
class PiEstimator
{
public:
PiEstimator() : m_engine(m_random_device()) {}
double operator()(long radius, unsigned long points_count)
{
auto points = generateListOfPoints(points_count, RandomPointGenerator<long>{m_engine, -radius, radius});
unsigned long points_count_in_circle = std::count_if(points.begin(), points.end(), inCircle(radius));
return 4.0 * points_count_in_circle / points_count;
}
private:
std::random_device m_random_device;
std::mt19937 m_engine;
};
template<long base>
std::vector<long> listOfPow(std::size_t count)
{
std::vector<long> values;
values.reserve(count);
for (long exponent = 0; exponent < count; ++exponent) {
values.push_back(std::pow(base, exponent));
}
return values;
}
double pi_error(double estimated_pi)
{
return std::abs(PI-estimated_pi);
}
int main()
{
PiEstimator pi_estimator;
for (long radius: listOfPow<10>(10)) {
for (long points_count: listOfPow<10>(7)) {
std::cout << pi_error(pi_estimator(radius, points_count)) << ' ';
}
std::cout << '\n';
}
std::cout << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment