Last active
July 31, 2021 05:21
-
-
Save minghao912/6d4897f922de4a6a2093764b3674063e to your computer and use it in GitHub Desktop.
Checks if a given hand is a valid Mahjong hand
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 "CheckValidity.h" | |
#include <iostream> | |
using namespace std; | |
int main() { | |
vector<int> hand = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 6}; | |
string validHand = (isValidHand(hand)) ? "true" : "false"; | |
cout << "Hand is valid: " << validHand << endl; | |
return 0; | |
} | |
bool isValidHand(vector<int> hand) { | |
// Get the possible pair value | |
vector<int> pairPossibleValue; | |
int remainder = getSum(&hand) % 3; | |
if (remainder == 0) | |
pairPossibleValue = {3, 6, 9}; | |
else if (remainder == 1) | |
pairPossibleValue = {2, 5, 8}; | |
else if (remainder == 2) | |
pairPossibleValue = {1, 4, 7}; | |
// Remove the pair from hand, if the pair is in the hand | |
vector<vector<int>> handsWithPairRemoved; | |
for (int value : pairPossibleValue) { | |
auto handWithPairRemoved = removeValue(hand, value); | |
if (handWithPairRemoved) | |
handsWithPairRemoved.push_back(*handWithPairRemoved); | |
} | |
// Check if the remaining hand can form triplets | |
for (vector<int> h : handsWithPairRemoved) | |
if (checkRemaining(h)) // If any one of the remaining hands are valid, then the hand is valid | |
return true; | |
// None of the hands with pair removed are valid, so return false | |
return false; | |
} | |
int getSum(vector<int>* const hand) { | |
int sum; | |
for (int i : *hand) | |
sum += i; | |
return sum; | |
} | |
optional<vector<int>> removeValue(vector<int> hand, int value) { | |
int numRemoved = 0; | |
for (auto it = hand.begin(); it != hand.end(); ) { | |
if (numRemoved == 2) | |
break; | |
if (*it == value) { | |
hand.erase(it); | |
numRemoved++; | |
} else it++; | |
} | |
if (numRemoved < 2) | |
return nullopt; | |
return hand; | |
} | |
bool checkRemaining(vector<int> hand) { | |
for (auto it = hand.begin(); it != hand.end(); ) { | |
if (hand.empty()) | |
return true; | |
if (it + 2 == hand.end()) | |
break; | |
int curPos = *it; | |
int posOne = *(it + 1); | |
int posTwo = *(it + 2); | |
// Check if there are pong or chi and remove them if so | |
if (curPos == posOne && posOne == posTwo) { | |
hand.erase(it + 2); | |
hand.erase(it + 1); | |
hand.erase(it); | |
} else if (curPos == posOne - 1 && posOne == posTwo - 1) { | |
hand.erase(it + 2); | |
hand.erase(it + 1); | |
hand.erase(it); | |
} else it++; // Increment one if no patterns found | |
} | |
// If valid, triplets would all be removed, leaving empty hand | |
return hand.empty(); | |
} |
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
#pragma once | |
#include <vector> | |
#include <optional> | |
bool isValidHand(std::vector<int> hand); | |
int getSum(std::vector<int>* const hand); | |
std::optional<std::vector<int>> removeValue(std::vector<int> hand, int value); | |
bool checkRemaining(std::vector<int> hand); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment