チンイツの待ちを出力するプログラム

あなたのスキルで飯は食えるか? 史上最大のコーディングスキル判定 (1/2) - ITmedia エンタープライズ
麻雀の待ち判定って一回作りたいとは思ってたけど、まだ作ったことなかったなー。
というわけで良い機会だし楽しそうなので挑戦してみました。…これで合ってるのかな。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

string anko(int n) {
	char buf[] = "(111)";
	buf[1] += n;
	buf[2] += n;
	buf[3] += n;
	return string(buf);
}

string shun(int n) {
	char buf[] = "(111)";
	buf[1] += n;
	buf[2] += n+1;
	buf[3] += n+2;
	return string(buf);
}

string atama(int n) {
	char buf[] = "(11)";
	buf[1] += n;
	buf[2] += n;
	return string(buf);
}

string ryan(int n) {
	char buf[] = "[11]";
	buf[1] += n;
	buf[2] += n+1;
	return string(buf);
}

string kan(int n) {
	char buf[] = "[11]";
	buf[1] += n;
	buf[2] += n+2;
	return string(buf);
}

string shabo(int n) {
	char buf[] = "[11]";
	buf[1] += n;
	buf[2] += n;
	return string(buf);
}

string tanki(int n) {
	char buf[] = "[1]";
	buf[1] += n;
	return string(buf);
}

void piyo(const vector<int>& a, string s) {
	//りゃんめん・ぺんちゃん
	for (int i = 0; i < 8; ++ i) {
		if (a[i] && a[i+1]) {
			cout << s << ryan(i) << endl;
		}
	}
	//かんちゃん
	for (int i = 0; i < 7; ++ i) {
		if (a[i] && a[i+2]) {
			cout << s << kan(i) << endl;
		}
	}
	//しゃぼ
	for (int i = 0; i < 9; ++ i) {
		if (a[i]>=2) {
			cout << s << shabo(i) << endl;
		}
	}
}

void fuga(const vector<int>& a, string s) {
	//単騎
	for (int i = 0; i < 9; ++ i) {
		if (a[i]) {
			cout << s << tanki(i) << endl;
		}
	}
}

void hoge(const vector<int>& a, int p, int men, string s) {
	if (men < 3) { // とりあえず適当に3面子作る
		//あんこ
		for (int i = p; i < 9; ++ i) {
			if (a[i]>=3) {
				vector<int> b = a;
				b[i] -= 3;
				hoge(b, i, men+1, s+anko(i));
			}
		}
		//しゅんつ
		for (int i = max(0,p-9); i <= 6; ++ i) {
			if (a[i] && a[i+1] && a[i+2]) {
				vector<int> b = a;
				-- b[i]; -- b[i+1]; -- b[i+2];
				hoge(b, i+9, men+1, s+shun(i));
			}
		}
	} else {
		//単騎以外
		for (int i = 0; i < 9; ++ i) {
			if (a[i] >= 2) {
				vector<int> b = a;
				b[i] -= 2;
				piyo(b, s+atama(i));
			}
		}
		//あんこ
		for (int i = p; i < 9; ++ i) {
			if (a[i]>=3) {
				vector<int> b = a;
				b[i] -= 3;
				fuga(b, s+anko(i));
			}
		}
		//しゅんつ
		for (int i = max(0,p-9); i <= 6; ++ i) {
			if (a[i] && a[i+1] && a[i+2]) {
				vector<int> b = a;
				-- b[i]; -- b[i+1]; -- b[i+2];
				fuga(b, s+shun(i));
			}
		}
	}
}

void func(string s) {
	vector<int> a(9,0);
	for (int i = 0; i < 13; ++ i) {
		++ a[ s[i]-'1' ];
	}
	hoge(a, 0, 0, "");
}

int main() {
	string buf;
	while (getline(cin,buf)) {
		cout << buf <<endl;
		func(buf);
	}
}

実行結果:

1112224588899
(111)(222)(888)(99)[45]
1122335556799
(555)(123)(123)(99)[67]
(123)(123)(567)(55)[99]
(123)(123)(567)(99)[55]
1112223335559
(111)(222)(333)(555)[9]
(555)(123)(123)(123)[9]
1223344888999
(888)(999)(123)(44)[23]
(888)(999)(123)(234)[4]
(888)(999)(234)(234)[1]
1112345678999
(111)(999)(234)(567)[8]
(111)(999)(234)(678)[5]
(111)(999)(345)(678)[2]
(111)(234)(567)(99)[89]
(111)(234)(789)(99)[56]
(111)(456)(789)(99)[23]
(999)(123)(456)(11)[78]
(999)(123)(678)(11)[45]
(999)(345)(678)(11)[12]
(123)(456)(789)(11)[99]
(123)(456)(789)(99)[11]

時間:1時間弱