#include <iostream>
#include <iomanip>
#include <random>
#include <cmath>
using namespace std;
// ==========================
// MONTE CARLO
// ==========================
long double monteCarloPi(unsigned long long n)
{
unsigned long long inside = 0;
random_device rd;
mt19937_64 gen(rd());
uniform_real_distribution<long double> dist(0.0L, 1.0L);
for (unsigned long long i = 0; i < n; ++i)
{
long double x = dist(gen);
long double y = dist(gen);
if (x * x + y * y <= 1.0L)
inside++;
}
return 4.0L * (long double)inside / (long double)n;
}
// ==========================
// METODA PROSTOKĄTÓW
// π = 4 ∫₀¹ 1/(1+x²) dx
// ==========================
long double rectanglePi(unsigned long long n)
{
long double sum = 0.0L;
long double h = 1.0L / n;
for (unsigned long long i = 0; i < n; ++i)
{
long double x = i * h;
sum += 1.0L / (1.0L + x * x);
}
return 4.0L * h * sum;
}
// ==========================
// METODA TRAPEZÓW
// ==========================
long double trapezoidPi(unsigned long long n)
{
long double h = 1.0L / n;
long double sum = 0.0L;
sum += 0.5L * (1.0L / (1.0L + 0.0L)); // f(0)
sum += 0.5L * (1.0L / (1.0L + 1.0L)); // f(1)
for (unsigned long long i = 1; i < n; ++i)
{
long double x = i * h;
sum += 1.0L / (1.0L + x * x);
}
return 4.0L * h * sum;
}
// ==========================
// MAIN
// ==========================
int main()
{
unsigned long long n = 100000000; // liczba iteracji/podziałów
long double piMonte = monteCarloPi(n);
long double piRect = rectanglePi(n);
long double piTrap = trapezoidPi(n);
cout << fixed << setprecision(20);
cout << "Monte Carlo: " << piMonte << endl;
cout << "Metoda prostokatow: " << piRect << endl;
cout << "Metoda trapezow: " << piTrap << endl;
return 0;
}