Last active
April 29, 2017 01:19
-
-
Save hkmix/a08b346f2e117ea5aa44f076710e5fac to your computer and use it in GitHub Desktop.
Pi Day Challenge entry
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 <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