Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@FredTingaud
Last active March 11, 2017 12:47
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 FredTingaud/5c6c7890f11abc07b9ad44dd68970150 to your computer and use it in GitHub Desktop.
Save FredTingaud/5c6c7890f11abc07b9ad44dd68970150 to your computer and use it in GitHub Desktop.
FredTingaud's proposal for Pi Day Challenge
#include <range/v3/all.hpp>
#include <iostream>
#include <iterator>
#include <random>
#include <iomanip>
using namespace ranges::v3;
std::random_device random_device;
std::mt19937 engine{random_device()};
static const double REF_PI = 3.14159265359;
struct Point
{
Point(int x1, int y1) : x(x1), y(y1) {}
int x, y;
};
auto randomPoint(int max)
{
std::uniform_int_distribution<int> dist(0, max);
return Point(dist(engine), dist(engine));
}
bool inCircle(const Point& p, int radius)
{
return p.x * p.x + p.y * p.y < radius * radius;
}
bool randomSample(int radius)
{
return inCircle(randomPoint(radius), radius);
}
int power10(int n)
{
return std::pow(10, n);
}
auto monteCarloEntries(int radius, int repeat)
{
return view::repeat_n(radius, repeat);
}
double monteCarloSampling(int radius, int repeat)
{
return 4. * distance(monteCarloEntries(radius, repeat) | view::filter(randomSample)) / repeat;
}
std::string formatResult(double result)
{
std::ostringstream os;
os << std::fixed << std::setfill(' ') << std::setw(15) << result;
return os.str();
}
auto resultPrinter(int radius)
{
return view::transform([=] (int repeat) {return std::abs(REF_PI - monteCarloSampling(radius, repeat));}) | view::transform(formatResult);
}
std::string printResultBySizeForRadius(int radius, int maxRepeats)
{
return view::iota(1, maxRepeats + 1) | view::transform(power10) | resultPrinter(radius) | action::join;
}
auto printResultBySize(int maxRepeats)
{
return view::transform([=] (int radius){return printResultBySizeForRadius(radius, maxRepeats); });
}
auto radiuses(int n)
{
return view::iota(1, n + 1) | view::transform(power10);
}
void runSampling(int n, int m)
{
copy(radiuses(n) | printResultBySize(m), ostream_iterator<>(std::cout, "\n"));
}
int main(int argc, char** argv)
{
if (argc == 3)
{
int radius;
int size;
std::istringstream isRad(argv[1]);
isRad >> radius;
std::istringstream isSize(argv[2]);
isSize >> size;
runSampling(radius, size);
}
else
std::cerr << "Usage: ./" << argv[0] << " radiusCount sizeCount" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment