|
#include <iostream> |
|
#include <string> |
|
#include <sstream> |
|
#include <algorithm> |
|
#include <vector> |
|
#include <set> |
|
using namespace std; |
|
|
|
inline int extractCount(int pattern, int pos) |
|
{ |
|
return (pattern >> (3 * pos)) & 7; |
|
} |
|
|
|
char suits[] = {'m', 'p', 's', 'z'}; |
|
vector<string> allPattern[4][13]; |
|
|
|
void output(int pattern, int sid) |
|
{ |
|
stringstream ss; |
|
int len = 0; |
|
for(int i = 0; i < 9; i++) |
|
{ |
|
int count = extractCount(pattern, i); |
|
len += count; |
|
for(int j = 0; j < count; j++) |
|
{ |
|
ss << (i+1) << suits[sid]; |
|
} |
|
} |
|
allPattern[sid][len-1].push_back(ss.str()); |
|
if(sid != 3 && (pattern >> (3*4)) & 7 >= 1) |
|
{ |
|
ss.str(""s); |
|
for(int i = 0; i < 9; i++) |
|
{ |
|
int count = extractCount(pattern, i); |
|
if(i == 4) {ss << '0' << suits[sid]; count--;} |
|
for(int j = 0; j < count; j++) |
|
{ |
|
ss << (i+1) << suits[sid]; |
|
} |
|
} |
|
allPattern[sid][len-1].push_back(ss.str()); |
|
} |
|
} |
|
|
|
set<int> numcache; |
|
void outputSuit(int pattern) |
|
{ |
|
if(numcache.count(pattern) > 0) return; |
|
numcache.insert(pattern); |
|
output(pattern, 0); |
|
output(pattern, 1); |
|
output(pattern, 2); |
|
} |
|
|
|
set<int> honorcache; |
|
void outputHonor(int pattern) |
|
{ |
|
if(honorcache.count(pattern) > 0) return; |
|
honorcache.insert(pattern); |
|
output(pattern, 3); |
|
} |
|
|
|
bool valid(int pattern) |
|
{ |
|
for(int i = 0; i < 9; i++) |
|
{ |
|
if(extractCount(pattern, i) > 4) return false; |
|
} |
|
return true; |
|
} |
|
|
|
int main() |
|
{ |
|
int threePattern[16]; |
|
for(int i = 0; i < 9; i++) threePattern[i] = 3 << (3 * i); |
|
for(int i = 0; i < 7; i++) threePattern[i+9] = 0111 << (3 * i); |
|
|
|
int twoPattern[24]; |
|
for(int i = 0; i < 9; i++) twoPattern[i] = 2 << (3 * i); |
|
for(int i = 0; i < 8; i++) twoPattern[i+9] = 011 << (3 * i); |
|
for(int i = 0; i < 7; i++) twoPattern[i+17] = 0101 << (3 * i); |
|
|
|
int onePattern[9]; |
|
for(int i = 0; i < 9; i++) onePattern[i] = 1 << (3 * i); |
|
|
|
#define ONE(p) for(int p : onePattern) |
|
#define TWO(p) for(int p : twoPattern) |
|
#define THREE(p) for(int p : threePattern) |
|
#define CHECK(p) if(valid(p)) |
|
#define OUT(p) outputSuit(p) |
|
#define CHECKOUT(p) CHECK(p) OUT(p) |
|
|
|
ONE(p1) OUT(p1); // 1 |
|
TWO(p1) |
|
{ |
|
OUT(p1); // 2 |
|
TWO(p2) CHECKOUT(p1+p2); // 2+2 |
|
} |
|
THREE(p1) |
|
{ |
|
OUT(p1); // 3 |
|
ONE(p2) CHECKOUT(p1+p2); // 3+1 |
|
TWO(p2) CHECK(p1+p2) |
|
{ |
|
OUT(p1+p2); // 3+2 |
|
TWO(p3) CHECKOUT(p1+p2+p3); // 3+2+2 |
|
} |
|
THREE(p2) CHECK(p1+p2) |
|
{ |
|
OUT(p1+p2); // 3+3 |
|
ONE(p3) CHECKOUT(p1+p2+p3); // 3+3+1 |
|
TWO(p3) CHECK(p1+p2+p3) |
|
{ |
|
OUT(p1+p2+p3); // 3+3+2 |
|
TWO(p4) CHECKOUT(p1+p2+p3+p4); // 3+3+2+2 |
|
} |
|
THREE(p3) CHECK(p1+p2+p3) |
|
{ |
|
OUT(p1+p2+p3); // 3+3+3 |
|
ONE(p4) CHECKOUT(p1+p2+p3+p4); // 3+3+3+1 |
|
TWO(p4) CHECK(p1+p2+p3+p4) |
|
{ |
|
OUT(p1+p2+p3+p4); // 3+3+3+2 |
|
TWO(p5) CHECKOUT(p1+p2+p3+p4+p5); // 3+3+3+2+2 |
|
} |
|
THREE(p4) CHECK(p1+p2+p3+p4) |
|
{ |
|
OUT(p1+p2+p3+p4); // 3+3+3+3 |
|
ONE(p5) CHECKOUT(p1+p2+p3+p4+p5); // 3+3+3+3+1 |
|
} |
|
} |
|
} |
|
} |
|
|
|
int triplePattern[7]; |
|
int doublePattern[7]; |
|
int singlePattern[7]; |
|
for(int i = 0; i < 7; i++) |
|
{ |
|
triplePattern[i] = 3 << (3 * i); |
|
doublePattern[i] = 2 << (3 * i); |
|
singlePattern[i] = 1 << (3 * i); |
|
} |
|
|
|
#undef ONE |
|
#undef TWO |
|
#undef THREE |
|
#undef OUT |
|
#undef CHECKOUT |
|
#define ONE(p) for(int p : singlePattern) |
|
#define TWO(p) for(int p : doublePattern) |
|
#define THREE(p) for(int p : triplePattern) |
|
#define OUT(p) outputHonor(p) |
|
#define CHECKOUT(p) CHECK(p) OUT(p) |
|
|
|
ONE(p1) OUT(p1); // 1 |
|
TWO(p1) |
|
{ |
|
OUT(p1); // 2 |
|
TWO(p2) CHECKOUT(p1+p2); // 2+2 |
|
} |
|
THREE(p1) |
|
{ |
|
OUT(p1); // 3 |
|
ONE(p2) CHECKOUT(p1+p2); // 3+1 |
|
TWO(p2) CHECK(p1+p2) |
|
{ |
|
OUT(p1+p2); // 3+2 |
|
TWO(p3) CHECKOUT(p1+p2+p3); // 3+2+2 |
|
} |
|
THREE(p2) CHECK(p1+p2) |
|
{ |
|
OUT(p1+p2); // 3+3 |
|
ONE(p3) CHECKOUT(p1+p2+p3); // 3+3+1 |
|
TWO(p3) CHECK(p1+p2+p3) |
|
{ |
|
OUT(p1+p2+p3); // 3+3+2 |
|
TWO(p4) CHECKOUT(p1+p2+p3+p4); // 3+3+2+2 |
|
} |
|
THREE(p3) CHECK(p1+p2+p3) |
|
{ |
|
OUT(p1+p2+p3); // 3+3+3 |
|
ONE(p4) CHECKOUT(p1+p2+p3+p4); // 3+3+3+1 |
|
TWO(p4) CHECK(p1+p2+p3+p4) |
|
{ |
|
OUT(p1+p2+p3+p4); // 3+3+3+2 |
|
TWO(p5) CHECKOUT(p1+p2+p3+p4+p5); // 3+3+3+2+2 |
|
} |
|
THREE(p4) CHECK(p1+p2+p3+p4) |
|
{ |
|
OUT(p1+p2+p3+p4); // 3+3+3+3 |
|
ONE(p5) CHECKOUT(p1+p2+p3+p4+p5); // 3+3+3+3+1 |
|
} |
|
} |
|
} |
|
} |
|
|
|
for(int sid = 0; sid < 4; sid++) |
|
{ |
|
cout << "const char* pattern_" << suits[sid] << "_0" << "[] = {\"\"};" << endl; |
|
for(int i = 0; i < 13; i++) |
|
{ |
|
cout << "const char* pattern_" << suits[sid] << "_" << (i+1) << "[] = {" << endl; |
|
sort(begin(allPattern[sid][i]), end(allPattern[sid][i])); |
|
for(string& s : allPattern[sid][i]) |
|
{ |
|
cout << "\t\"" << s << "\"," << endl; |
|
} |
|
cout << "};" << endl; |
|
} |
|
} |
|
cout << "const char** patternTable[4][14] = {"; |
|
for(int sid = 0; sid < 4; sid++) |
|
{ |
|
cout << "{"; |
|
for(int i = 0; i < 14; i++) |
|
{ |
|
cout << "pattern_" << suits[sid] << "_" << i << ", "; |
|
} |
|
cout << "}, "; |
|
} |
|
cout << "};" << endl; |
|
cout << "const int patternSize[4][14] = {"; |
|
for(int sid = 0; sid < 4; sid++) |
|
{ |
|
cout << "{1, "; |
|
for(int i = 0; i < 13; i++) |
|
{ |
|
cout << allPattern[sid][i].size() << ", "; |
|
} |
|
cout << "}, "; |
|
} |
|
cout << "};" << endl; |
|
|
|
return 0; |
|
} |