Skip to content

Instantly share code, notes, and snippets.

@kazmura11
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazmura11/10023067 to your computer and use it in GitHub Desktop.
Save kazmura11/10023067 to your computer and use it in GitHub Desktop.
#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;
}
@kazmura11
Copy link
Author

汚いコードなので参考にしないでくだしあ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment