Last active
August 29, 2015 13:58
-
-
Save kazmura11/10023067 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 <iostream> | |
#include <string> | |
#include <vector> | |
#include <algorithm> | |
const int CardNumber = 13; | |
const int JokerIndex = 13; | |
enum SuitElement | |
{ | |
C, D, H, S, Jo | |
}; | |
struct Suit | |
{ | |
SuitElement se_; | |
Suit(SuitElement se) | |
{ | |
se_ = se; | |
} | |
std::string toString() const | |
{ | |
std::string s; | |
switch (se_) | |
{ | |
case C: s = "Clover "; break; | |
case D: s = "Diamond"; break; | |
case H: s = "Heart "; break; | |
case S: s = "Spade "; break; | |
case Jo: s = "Joker "; break; | |
} | |
return s; | |
} | |
}; | |
class Card | |
{ | |
public: | |
Card(const std::string& s); | |
SuitElement getSuit() const; | |
int getNumber() const; | |
std::string getName() const; | |
std::string getSuitName() const; | |
bool operator<(const Card& rhs) const; | |
bool operator==(const Card& rhs) const; | |
private: | |
void set(const std::string& s); | |
Suit suit_; | |
int number_; | |
std::string name_; | |
}; | |
Card::Card(const std::string& s) | |
: suit_(Jo), number_(0), name_("") | |
{ | |
set(s); | |
} | |
SuitElement Card::getSuit() const | |
{ | |
return suit_.se_; | |
} | |
int Card::getNumber() const | |
{ | |
return number_; | |
} | |
std::string Card::getName() const | |
{ | |
return name_; | |
} | |
std::string Card::getSuitName() const | |
{ | |
return suit_.toString(); | |
} | |
void Card::set(const std::string& s) | |
{ | |
switch (s[0]) | |
{ | |
case 'C': suit_ = C; break; | |
case 'D': suit_ = D; break; | |
case 'H': suit_ = H; break; | |
case 'S': suit_ = S; break; | |
default: suit_ = Jo; break; | |
} | |
switch (s[1]) | |
{ | |
case '3': number_ = 0; break; | |
case '4': number_ = 1; break; | |
case '5': number_ = 2; break; | |
case '6': number_ = 3; break; | |
case '7': number_ = 4; break; | |
case '8': number_ = 5; break; | |
case '9': number_ = 6; break; | |
case 'T': number_ = 7; break; | |
case 'J': number_ = 8; break; | |
case 'Q': number_ = 9; break; | |
case 'K': number_ = 10; break; | |
case 'A': number_ = 11; break; | |
case '2': number_ = 12; break; | |
case 'o': number_ = 13; break; | |
} | |
name_ = s; | |
} | |
bool Card::operator<(const Card& rhs) const | |
{ | |
if (number_ < rhs.number_) { return true; } | |
else if (number_ == rhs.number_) | |
{ | |
if (suit_.se_ < rhs.suit_.se_) { return true; } | |
else { return false; } | |
} | |
else { return false; } | |
} | |
bool Card::operator==(const Card& rhs) const | |
{ | |
if (number_ == rhs.number_) | |
{ | |
if (suit_.se_ == rhs.suit_.se_) { return true; } | |
} | |
return false; | |
} | |
class CardHelper | |
{ | |
public: | |
CardHelper(const std::string& s); | |
void dump(); | |
std::string getCandidate(); | |
private: | |
void setFieldPairNum(); | |
void setHandPairNum(); | |
std::vector<Card> field_; | |
int fieldPairNum_[CardNumber+1]; | |
std::vector<Card> hand_; | |
int handPairNum_[CardNumber+1]; | |
}; | |
CardHelper::CardHelper(const std::string& s) | |
{ | |
// Analyze field cards | |
int index = s.find(","); | |
for (int i = 0; i < index - 1; i += 2) | |
{ | |
field_.push_back(Card(s.substr(i, 2))); | |
} | |
// Analyze hand cards | |
int length = s.length(); | |
for (int i = index + 1; i < length; i += 2) | |
{ | |
hand_.push_back(Card(s.substr(i, 2))); | |
} | |
// sort | |
std::sort(field_.begin(), field_.end()); | |
std::sort(hand_.begin(), hand_.end()); | |
// set numbers of pair | |
setFieldPairNum(); | |
setHandPairNum(); | |
} | |
void CardHelper::setFieldPairNum() | |
{ | |
for (int i = 0; i < CardNumber+1; i++) | |
{ | |
fieldPairNum_[i] = 0; | |
} | |
int prevNumber = -1; | |
int cnt = 1; | |
for (auto it = field_.begin(); it != field_.end(); ++it) | |
{ | |
if (prevNumber == it->getNumber()) { cnt++; } | |
else { cnt = 1; } | |
fieldPairNum_[it->getNumber()] = cnt; | |
prevNumber = it->getNumber(); | |
} | |
} | |
void CardHelper::setHandPairNum() | |
{ | |
for (int i = 0; i < CardNumber+1; i++) | |
{ | |
handPairNum_[i] = 0; | |
} | |
int prevNumber = -1; | |
int cnt = 1; | |
for (auto it = hand_.begin(); it != hand_.end(); ++it) | |
{ | |
if (prevNumber == it->getNumber()) { cnt++; } | |
else { cnt = 1; } | |
handPairNum_[it->getNumber()] = cnt; | |
prevNumber = it->getNumber(); | |
} | |
} | |
// for debuging | |
void CardHelper::dump() | |
{ | |
std::cout << "[filed cards]" << std::endl; | |
for (auto it = field_.begin(); it != field_.end(); ++it) | |
{ | |
std::cout << it->getName() | |
<< " suitname: " << it->getSuitName() | |
<< " strength: " << it->getNumber() << std::endl; | |
} | |
std::cout << "[hand cards]" << std::endl; | |
for (auto it = hand_.begin(); it != hand_.end(); ++it) | |
{ | |
std::cout << it->getName() | |
<< " suitname: " << it->getSuitName() | |
<< " strength: " << it->getNumber() << std::endl; | |
} | |
for (int i = 0; i < CardNumber+1; i++) | |
{ | |
std::cout << i << ":" << fieldPairNum_[i] << " "; | |
} | |
std::cout << std::endl; | |
for (int i = 0; i < CardNumber+1; i++) | |
{ | |
std::cout << i << ":" << handPairNum_[i] << " "; | |
} | |
std::cout << std::endl; | |
} | |
std::string CardHelper::getCandidate() | |
{ | |
std::string answer = ""; | |
auto rFieldIt = field_.rbegin(); | |
int maxValue; | |
int fieldPairNum; | |
int fieldJokerNum = fieldPairNum_[JokerIndex]; | |
if (static_cast<int>(field_.size()) > fieldJokerNum) | |
{ | |
rFieldIt += fieldJokerNum; | |
} | |
maxValue = rFieldIt->getNumber(); | |
fieldPairNum = fieldPairNum_[maxValue]; | |
int index = 0; | |
bool isFirst = true; | |
int handPairNum = 0; | |
int handValue = 0; | |
int handJokerNum = handPairNum_[JokerIndex]; | |
for (int i = 0; i < static_cast<int>(hand_.size()) - handJokerNum;) | |
{ | |
handValue = hand_[i].getNumber(); | |
if (handValue > maxValue) | |
{ | |
handPairNum = handPairNum_[handValue]; | |
if (handPairNum + handJokerNum >= fieldPairNum + fieldJokerNum) | |
{ | |
// extract pairs of cards and convert to string | |
// start pos and slide pos | |
for (int j = 0; | |
j < ((handPairNum + handJokerNum) - (fieldPairNum + fieldJokerNum) + 1); | |
j++) | |
{ | |
if (fieldPairNum + fieldJokerNum == 1) | |
{ | |
if (!isFirst) | |
{ | |
answer += ","; | |
} | |
else | |
{ | |
isFirst = false; | |
} | |
answer += hand_[i + j].getName(); | |
} | |
else if (fieldPairNum + fieldJokerNum == 2) | |
{ | |
for (int k = j + 1; k < handPairNum + handJokerNum; k++) | |
{ | |
if (!isFirst) | |
{ | |
answer += ","; | |
} | |
else | |
{ | |
isFirst = false; | |
} | |
answer += hand_[i + j].getName(); | |
if ((handJokerNum == 1 || handJokerNum == 2) | |
&& k == (handPairNum + handJokerNum - 1)) | |
{ | |
answer += "Jo"; | |
} | |
else | |
{ | |
answer += hand_[i + k].getName(); | |
} | |
} | |
} | |
else if (fieldPairNum + fieldJokerNum == 3) | |
{ | |
for (int k = j + 1; k < handPairNum + handJokerNum; k++) | |
{ | |
for (int l = k + 1; l < handPairNum + handJokerNum; l++) | |
{ | |
if (!isFirst) | |
{ | |
answer += ","; | |
} | |
else | |
{ | |
isFirst = false; | |
} | |
answer += hand_[i + j].getName(); | |
if ((handJokerNum == 1 || handJokerNum == 2) | |
&& k == (handPairNum + handJokerNum - 1)) | |
{ | |
answer += "Jo"; | |
} | |
else | |
{ | |
answer += hand_[i + k].getName(); | |
} | |
if ((handJokerNum == 1 || handJokerNum == 2) | |
&& l == (handPairNum + handJokerNum - 1)) | |
{ | |
answer += "Jo"; | |
} | |
else | |
{ | |
answer += hand_[i + l].getName(); | |
} | |
} | |
} | |
} | |
else if (fieldPairNum + fieldJokerNum == 4) | |
{ | |
for (int k = j + 1; k < handPairNum + handJokerNum; k++) | |
{ | |
for (int l = k + 1; l < handPairNum + handJokerNum; l++) | |
{ | |
for (int m = l + 1; m < handPairNum + handJokerNum; m++) | |
{ | |
if (!isFirst) | |
{ | |
answer += ","; | |
} | |
else | |
{ | |
isFirst = false; | |
} | |
answer += hand_[i + j].getName(); | |
if ((handJokerNum == 1 || handJokerNum == 2) | |
&& k == (handPairNum + handJokerNum - 1)) | |
{ | |
answer += "Jo"; | |
} | |
else | |
{ | |
answer += hand_[i + k].getName(); | |
} | |
if ((handJokerNum == 1 || handJokerNum == 2) | |
&& l == (handPairNum + handJokerNum - 1)) | |
{ | |
answer += "Jo"; | |
} | |
else | |
{ | |
answer += hand_[i + l].getName(); | |
} | |
if ((handJokerNum == 1 || handJokerNum == 2) | |
&& l == (handPairNum + handJokerNum - 1)) | |
{ | |
answer += "Jo"; | |
} | |
else | |
{ | |
answer += hand_[i + m].getName(); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
i += handPairNum; | |
} | |
else | |
{ | |
i++; | |
} | |
} | |
if (answer.empty()) | |
{ | |
answer = "-"; | |
} | |
return answer; | |
} | |
void test(const std::string question, const std::string answer) | |
{ | |
static int qno = 1; // question number | |
std::cout << "/*#" << qno++ << "*/" << std::endl; | |
std::string ret; | |
CardHelper ch(question); | |
ret = ch.getCandidate(); | |
std::cout << "question : " << question << std::endl; | |
std::cout << "answer : " << answer << std::endl; | |
std::cout << "ret : " << ret << std::endl; | |
std::cout << std::endl; | |
//ch.dump(); | |
} | |
int main() | |
{ | |
/*#1*/ test("DJ,", "-"); | |
/*#2*/ test("H7,HK", "HK"); | |
/*#3*/ test("S3,D4D2", "D4,D2"); | |
/*#4*/ test("S9,C8H4", "-"); | |
/*#5*/ test("S6,S7STCK", "CK,ST,S7"); | |
/*#6*/ test("H4,SAS8CKH6S4", "S8,CK,H6,SA"); | |
/*#7*/ test("ST,D6S8JoC7HQHAC2CK", "Jo,C2,CK,HA,HQ"); | |
/*#8*/ test("SA,HAD6S8S6D3C4H2C5D4CKHQS7D5", "H2"); | |
/*#9*/ test("S2,D8C9D6HQS7H4C6DTS5S6C7HAD4SQ", "-"); | |
/*#10*/ test("Jo,HAC8DJSJDTH2", "-"); | |
/*#11*/ test("S4Jo,CQS6C9DQH9S2D6S3", "DQCQ,D6S6,H9C9"); | |
/*#12*/ test("CTDT,S9C2D9D3JoC6DASJS4", "JoC2,SJJo,DAJo"); | |
/*#13*/ test("H3D3,DQS2D6H9HAHTD7S6S7Jo", "JoHA,JoD6,JoH9,D6S6,D7S7,JoS6,HTJo,JoDQ,S2Jo,JoD7,JoS7"); | |
/*#14*/ test("D5Jo,CQDAH8C6C9DQH7S2SJCKH5", "CQDQ"); | |
/*#15*/ test("C7H7,S7CTH8D5HACQS8JoD6SJS5H4", "HAJo,JoSJ,H8S8,H8Jo,CQJo,CTJo,JoS8"); | |
/*#16*/ test("SAHA,S7SKCTS3H9DJHJH7S5H2DKDQS4", "-"); | |
/*#17*/ test("JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT", "CTDT,H9D9,S9D9,DACA,CTST,H9S9,DTST"); | |
/*#18*/ test("HTST,SJHJDJCJJoS3D2", "DJCJ,SJDJ,JoHJ,CJHJ,SJJo,HJSJ,DJJo,JoCJ,JoD2,SJCJ,DJHJ"); | |
/*#19*/ test("C7D7,S8D8JoCTDTD4CJ", "D8S8,JoS8,CTJo,DTJo,JoCJ,CTDT,D8Jo"); | |
/*#20*/ test("DJSJ,DTDKDQHQJoC2", "JoDK,HQDQ,DQJo,C2Jo,JoHQ"); | |
/*#21*/ test("C3H3D3,CKH2DTD5H6S4CJS5C6H5S9CA", "S5H5D5"); | |
/*#22*/ test("D8H8S8,CQHJCJJoHQ", "JoCQHQ,JoHJCJ"); | |
/*#23*/ test("H6D6S6,H8S8D8C8JoD2H2", "D2H2Jo,D8JoS8,D8S8C8,C8D8H8,JoC8S8,H8JoC8,S8H8C8,JoS8H8,C8JoD8,D8H8S8,D8JoH8"); | |
/*#24*/ test("JoD4H4,D3H3S3C3CADASAD2", "DACASA"); | |
/*#25*/ test("DJHJSJ,SQDQJoHQCQC2CA", "SQJoCQ,DQCQJo,JoSQHQ,SQCQHQ,DQHQSQ,HQDQCQ,HQDQJo,SQDQCQ,CQJoHQ,SQJoDQ"); | |
/*#26*/ test("H3D3Jo,D4SKH6CTS8SAS2CQH4HAC5DADKD9", "HASADA"); | |
/*#27*/ test("C3JoH3D3,S2S3H7HQCACTC2CKC6S7H5C7", "-"); | |
/*#28*/ test("H5C5S5D5,C7S6D6C3H7HAH6H4C6HQC9", "C6D6S6H6"); | |
/*#29*/ test("H7S7C7D7,S5SAH5HAD5DAC5CA", "SADACAHA"); | |
/*#30*/ test("D4H4S4C4,S6SAH6HAD6DAC6CAJo", "C6H6S6D6,SAJoDACA,S6H6C6Jo,SACAJoHA,HADASAJo,HADAJoCA,CADAHASA,D6C6JoH6,S6D6C6Jo,H6JoS6D6"); | |
/*#31*/ test("DTCTSTHT,S3SQH3HQD3DQC3CQJo", "HQSQJoDQ,SQCQDQJo,DQCQHQJo,SQHQJoCQ,CQDQHQSQ"); | |
/*#32*/ test("JoS8D8H8,S9DTH9CTD9STC9CAC2", "H9C9D9S9"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
汚いコードなので参考にしないでくだしあ