#include <iostream>
#include <iomanip>
#include <random>
#include <cmath>
using namespace std;
// ================= MONTE CARLO =================
long double monteCarlo(unsigned long long n) {
mt19937_64 gen(123456); // stałe ziarno dla powtarzalności
uniform_real_distribution<long double> dist(-1.0L, 1.0L);
unsigned long long inside = 0;
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 =================
long double rectangleMethod(unsigned long long n) {
long double h = 1.0L / (long double)n;
long double sum = 0.0L;
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 trapezoidalMethod(unsigned long long n) {
long double h = 1.0L / (long double)n;
long double sum = 0.0L;
sum += 0.5L * (1.0L / (1.0L + 0.0L * 0.0L));
sum += 0.5L * (1.0L / (1.0L + 1.0L * 1.0L));
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 nMonteCarlo = 100000000ULL; // 100 mln punktów
unsigned long long nIntegral = 100000000ULL;
cout << fixed << setprecision(30);
long double piMonteCarlo = monteCarlo(nMonteCarlo);
long double piRectangle = rectangleMethod(nIntegral);
long double piTrapezoid = trapezoidalMethod(nIntegral);
cout << "Monte Carlo (100 000 000 punktów):\n";
cout << piMonteCarlo << endl << endl;
cout << "Metoda prostokatow:\n";
cout << piRectangle << endl << endl;
cout << "Metoda trapezow:\n";
cout << piTrapezoid << endl;
return 0;
}