Skip to content

Instantly share code, notes, and snippets.

@hkmix
Last active April 29, 2017 01:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hkmix/a08b346f2e117ea5aa44f076710e5fac to your computer and use it in GitHub Desktop.
Save hkmix/a08b346f2e117ea5aa44f076710e5fac to your computer and use it in GitHub Desktop.
Pi Day Challenge entry
#include <iostream>
#include <iomanip>
#include <random>
#include <string>
#include <thread>
#include <vector>
using std::size_t;
class Point {
private:
double x_;
double y_;
public:
Point(double x, double y)
: x_(x), y_(y)
{
}
static Point random_point(double square_width)
{
static std::random_device rd;
static std::mt19937 rng{rd()};
std::uniform_real_distribution<double> dist(0, square_width);
return Point{dist(rng), dist(rng)};
}
double distance_to(const Point& other) const
{
return std::sqrt(std::pow(x_ - other.x_, 2) +
std::pow(y_ - other.y_, 2));
}
}; // Point
namespace {
size_t pow(size_t base, size_t exp)
{
size_t result = 1;
while (exp > 0) {
result *= base;
--exp;
}
return result;
}
} // namespace
int main()
{
// Constants
static constexpr double PI_COUNT_MULTIPLIER = 4.0;
static constexpr double PI_REF = 3.14159265359;
static constexpr size_t MAX_COUNT_POW = 7;
static constexpr size_t MAX_RADIUS_POW = 9;
std::vector<std::thread> workers;
double error_table[MAX_COUNT_POW][MAX_RADIUS_POW];
// Spawn workers
for (size_t c_pow = 0; c_pow < MAX_COUNT_POW; ++c_pow) {
for (size_t r_pow = 0; r_pow < MAX_RADIUS_POW; ++r_pow) {
workers.push_back(std::thread{[c_pow, r_pow, &error_table] {
const size_t count = pow(10, c_pow);
const size_t radius = pow(10, r_pow);
const size_t width = radius * 2;
size_t points_in_circle = 0;
const Point centre{static_cast<double>(radius),
static_cast<double>(radius)};
for (size_t i = 0; i < count; ++i) {
if (Point::random_point(width).distance_to(centre) <= radius) {
++points_in_circle;
}
}
double approx_pi = PI_COUNT_MULTIPLIER * points_in_circle / count;
error_table[c_pow][r_pow] = std::abs(approx_pi - PI_REF);
}});
}
}
for (auto& worker : workers) {
worker.join();
}
// Print table values
for (size_t r_pow = 0; r_pow < MAX_RADIUS_POW; ++r_pow) {
for (size_t c_pow = 0; c_pow < MAX_COUNT_POW; ++c_pow) {
std::cout << std::setw(12) << error_table[c_pow][r_pow];
}
std::cout << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment