#include <iostream>
#include <bits/stdc++.h>
using namespace std;
vector<int> hats;
vector<int> pl;
vector<vector<int>> blob;
int depth;
void f() {
if (depth == 7) {
for (int hid_hats = 0; hid_hats < 3; hid_hats++) {
while (hats[hid_hats] > 0) {
hats[hid_hats]--;
pl.push_back(hid_hats);
}
}
hats[pl[7]]++;
hats[pl[8]]++;
pl.push_back(0); // this is the cancelled flag
blob.push_back(pl);
pl.pop_back();
pl.pop_back();
pl.pop_back();
return;
}
for (int ix = 0; ix < 3; ix++) {
if (hats[ix] > 0) {
hats[ix]--;
pl.push_back(ix);
depth++;
f();
depth--;
pl.pop_back();
hats[ix]++;
if (hats[ix] == 3) {
break;
}
}
}
}
vector<int> renumber(vector<int> v) {
vector<int> res(9);
vector<int> pos(3);
pos[0] = pos[1] = pos[2] = -1;
for (int ix = 0; ix < 9; ix++) {
for (int num = 0; num < 3; num++) {
if ((v[ix] == num) && (pos[num]) < 0) {
pos[num] = ix;
}
}
}
sort(pos.begin(), pos.end());
for (int ix = 0; ix < 9; ix++) {
for (int num = 0; num < 3; num++) {
if (v[ix] == v[pos[num]]) {
res[ix] = num;
}
}
}
return res;
}
int main()
{
vector<int> unique_pol_vect = {0,0,0,1,0,1,1};
hats.push_back(3);
hats.push_back(3);
hats.push_back(3);
depth = 0;
f();
for (int filter_ix = 0; filter_ix < 7; filter_ix++) {
// apply filter position 0
int filter = filter_ix;
bool unique_pol = unique_pol_vect[filter_ix]; // to satisfy filter... 0: wanted not unique, 1: wanted unique
bool is_unique = 0;
bool filter_sat = 0;
#define CANCEL_FLAG 9
cout << endl << endl << "Remaining before filter... " << filter << endl;
for (int ix = 0; ix < (int)blob.size(); ix++) {
if (blob[ix][CANCEL_FLAG] == 0) { // not cancelled
printf("%4d) ", ix);
for (int iy = 0; iy < 10; iy++) {
printf("%2d", blob[ix][iy]);
}
printf("\n", ix);
}
}
cout << endl << endl << "Filter " << filter << endl;
for (int ix = 0; ix < (int)blob.size(); ix++) {
if (blob[ix][CANCEL_FLAG] == 0) { // not cancelled
vector<int> B_AC, C_AB, hid;
int pos_B_AC = -1, pos_C_AB = -1;
bool exists_B_AC=false, exists_C_AB=false;
// build vector B_ordAC
B_AC = vector<int>(blob[ix].begin(), blob[ix].begin()+7);
B_AC[filter] = blob[ix][7];
hid.push_back(blob[ix][filter]);
hid.push_back(blob[ix][8]);
B_AC.insert(B_AC.end(), hid.begin(), hid.end());
B_AC = renumber(B_AC);
sort(B_AC.begin()+7, B_AC.begin()+9);
// build vector C_ordAB
C_AB = vector<int>(blob[ix].begin(), blob[ix].begin()+7);
C_AB[filter] = blob[ix][8];
hid.resize(0);
hid.push_back(blob[ix][filter]);
hid.push_back(blob[ix][7]);
C_AB.insert(C_AB.end(), hid.begin(), hid.end());
C_AB = renumber(C_AB);
sort(C_AB.begin()+7, C_AB.begin()+9);
// check if exists B_AC
for (int iy = 0; iy < (int)blob.size(); iy++) {
if (blob[iy][CANCEL_FLAG] == 0) { // not cancelled
bool exists = true;
for (int iz = 0; iz < 9; iz++) {
if (blob[iy][iz] != B_AC[iz]) {
exists = false;
break;
}
}
if (exists == true) {
exists_B_AC = true;
pos_B_AC = iy;
break;
}
}
}
// check if exists C_AB
for (int iy = 0; iy < (int)blob.size(); iy++) {
if (blob[iy][9] == false) {
bool exists = true;
for (int iz = 0; iz < 9; iz++) {
if (blob[iy][iz] != C_AB[iz]) {
exists = false;
break;
}
}
if (exists == true) {
exists_C_AB = true;
pos_C_AB = iy;
}
}
}
// chek uniqueness
if (blob[ix][7] == blob[ix][8]) {
if (blob[ix][filter] == blob[ix][8]) {
is_unique = true;
} else {
is_unique = !exists_B_AC;
}
} else {
if (blob[ix][filter] == blob[ix][7]) {
is_unique = !exists_C_AB;
} else {
if (blob[ix][filter] == blob[ix][8]) {
is_unique = !exists_B_AC;
} else {
is_unique = !exists_B_AC && !exists_C_AB;
}
}
}
// apply polarity
filter_sat = is_unique == unique_pol;
if (filter_sat == false) {
cout << "Cancelling " << ix << endl;
blob[ix][CANCEL_FLAG] = 1; // cancelled
if (exists_B_AC) {
cout << "Cancelling " << pos_B_AC << endl;
blob[pos_B_AC][CANCEL_FLAG]++; // cancelled
}
if (exists_C_AB) {
cout << "Cancelling " << pos_C_AB << endl;
blob[pos_C_AB][CANCEL_FLAG]++; // cancelled
}
}
}
}
}
cout << endl << endl << "Colori " << endl;
for (int ix = 0; ix < (int)blob.size(); ix++) {
if (blob[ix][CANCEL_FLAG] == 0) { // not cancelled
vector<int> col(3);
col[0] = blob[ix][5]; // giallo
col[1] = blob[ix][6]; // verde
col[2] = blob[ix][3]; // rosso
printf("%4d) ", ix);
for (int iy = 0; iy < 9; iy++) {
char let;
if (blob[ix][iy] == col[0]) let = 'G';
if (blob[ix][iy] == col[1]) let = 'V';
if (blob[ix][iy] == col[2]) let = 'R';
if (iy == 7) printf(" nasc ");
printf(" %c", let);
}
printf("\n", ix);
}
}
cout << "Hello World!" << endl;
return 0;
}