Created
July 22, 2020 06:24
-
-
Save shivanshu3/9f44139d363fb617f19dcdc4a38f21b9 to your computer and use it in GitHub Desktop.
This file contains 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 "stdafx.h" | |
uint32_t GetCardValue(uint32_t card) | |
{ | |
return card % 13; | |
} | |
std::vector<uint32_t> GenerateCards() | |
{ | |
constexpr size_t numCards = 52; | |
std::vector<uint32_t> cards(numCards); | |
for (size_t i = 0; i < numCards; ++i) | |
cards[i] = static_cast<uint32_t>(i); | |
return cards; | |
} | |
std::mt19937& GetRandomBitGenerator() | |
{ | |
static std::random_device randomDevice; | |
static std::mt19937 randomBitGenerator(randomDevice()); | |
return randomBitGenerator; | |
} | |
void ShuffleCards(std::vector<uint32_t>& cards) | |
{ | |
auto& randomBitGenerator = GetRandomBitGenerator(); | |
std::shuffle(cards.begin(), cards.end(), randomBitGenerator); | |
} | |
uint64_t NumAdjacentPairs(const std::vector<uint32_t>& cards) | |
{ | |
uint64_t numPairs = 0; | |
for (size_t i = 0; i < 51; ++i) | |
{ | |
const auto& currentCard = cards[i]; | |
const auto& nextCard = cards[i + 1]; | |
if (GetCardValue(currentCard) == GetCardValue(nextCard)) | |
++numPairs; | |
} | |
return numPairs; | |
} | |
double AvgNumAdjacentPairs(size_t numShuffles) | |
{ | |
auto cards = GenerateCards(); | |
uint64_t totalNumPairs = 0; | |
for (size_t i = 0; i < numShuffles; ++i) | |
{ | |
ShuffleCards(cards); | |
auto numPairs = NumAdjacentPairs(cards); | |
totalNumPairs += numPairs; | |
} | |
return static_cast<double>(totalNumPairs) / static_cast<double>(numShuffles); | |
} | |
double NumPairsOnAllCores(size_t numShufflesPerCore) | |
{ | |
unsigned numThreads = std::thread::hardware_concurrency(); | |
std::vector<double> answers; | |
std::mutex answersMutex; | |
auto runCalc = [&]() -> void | |
{ | |
auto numPairs = AvgNumAdjacentPairs(numShufflesPerCore); | |
std::lock_guard<std::mutex> answersLock { answersMutex }; | |
answers.push_back(numPairs); | |
}; | |
std::vector<std::thread> threads; | |
for (unsigned i = 0; i < numThreads; ++i) | |
threads.emplace_back(runCalc); | |
for (unsigned i = 0; i < numThreads; ++i) | |
threads[i].join(); | |
double avgAnswer = 0; | |
for (const auto& answer : answers) | |
avgAnswer += answer; | |
avgAnswer /= numThreads; | |
return avgAnswer; | |
} | |
int wmain(int argc, wchar_t** argv) | |
{ | |
auto numShufflesPerCore = std::stoul(argv[1]); | |
auto startTime = std::chrono::steady_clock::now(); | |
auto numPairs = NumPairsOnAllCores(numShufflesPerCore); | |
auto endTime = std::chrono::steady_clock::now(); | |
auto analysisTotalTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count(); | |
auto numSeconds = static_cast<double>(analysisTotalTimeMs) / static_cast<double>(1000); | |
std::wcout << L"Num Pairs: " << numPairs << std::endl; | |
std::wcout << L"Analysis time: " << numSeconds << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment