#include <random>
#include <iostream>
#include <thread>
#include "ScopedTimer.h"

using namespace std;

void FindSmallestLargestSquareRootSum(int threadNum, int numThreads, double* smallArray, double* largeArray)
{
	const int totalCalcs = 100;

	int start = (totalCalcs * threadNum) / numThreads;
	int end = (totalCalcs * (threadNum + 1)) / numThreads;

	random_device rd;
	mt19937 rng(rd());
	uniform_real_distribution<double> dist(1.0, 10.0);

	double smallest = numeric_limits<double>::max();
	double largest = -1.0;

	for (int i = start; i < end; i++)
	{
		double num = 0.0;
		for (int j = 0; j < 10000000; j++)
		{
			num += sqrt(dist(rng));
		}

		if (num < smallest)
		{
			smallest = num;
		}

		if (num > largest)
		{
			largest = num;
		}
	}

	smallArray[threadNum] = smallest;
	largeArray[threadNum] = largest;
}


int main(int argc, char** argv)
{
	const int numThreads = thread::hardware_concurrency();

	ScopedTimer* timer = new ScopedTimer("Parallel run time");
	double* smallest = new double[numThreads];
	double* largest = new double[numThreads];

	vector<thread*> threads;

	for (int i = 0; i < numThreads; i++)
	{
		threads.push_back(new thread([i, numThreads, smallest, largest] {FindSmallestLargestSquareRootSum(i, numThreads, smallest, largest); }));
	}

	for (auto t : threads)
	{
		t->join();
		delete t;
	}

	double smallestVal = numeric_limits<double>::max();
	double largestVal = -1.0;

	for (int i = 0; i < numThreads; i++)
	{
		if (smallest[i] < smallestVal)
		{
			smallestVal = smallest[i];
		}

		if (largest[i] > largestVal)
		{
			largestVal = largest[i];
		}
	}

	delete timer;

	cout << "Smallest: " << smallestVal << endl << "Largest: " << largestVal << endl;
}