#include <iostream>
#include <vector>
#include <deque>
using namespace std;
/*
level 1 = 3 unique: {1,2,3} = 1 tuple
level 2 = 4 unique: {1,2,3} {1,2,4} + {1,3,4} + 1 = 3 + 1 = 4 tuples
level 3 = 5 unique: {1,2,3} {1,2,4} {1,2,5} + {1,3,4} {1,3,5} + {1,4,5} + 4 = 10 tuples
level 4 = 6 unique: {1,2,3} {1,2,4} {1,2,5} {1,2,6} + {1,3,4} {1,3,5} {1,3,6} {1,4,5} {1,4,6} {1,5,6} + 10 = 20
*/
typedef vector<int> Triplet;
int getSumSequence(int n)
{
if (n <= 0)
return 0;
return n + getSumSequence(n - 1);
}
int countTriplets(int index, int unique)
{
int level = unique - index - 2;
if (level < 1)
return 0;
if (level == 1)
return 1;
return getSumSequence(level);
}
//BFS approach
void countTriplets(const int * arr, int length, vector<Triplet*>& triplets)
{
//first count number of unique elements to avoid duplicates
int unique = 1;
for (int i = 1; i < length; ++i)
{
if (arr[i - 1] != arr[i])
unique++;
}
deque<Triplet*> constructed;
int nConstructed = countTriplets(0, unique);
int elementID = 0;
for (int i = 0; i < length; ++i)
{
//skip doubles
if (i > 0 && arr[i - 1] == arr[i])
continue;
//Add new tuples to deque on this level
int nTriplets = countTriplets(elementID++, unique);
for (int t = 0; t < nTriplets; ++t)
{
Triplet *triplet = new Triplet();
constructed.push_front(triplet);
}
//Process existing tuples in deque by adding arr[i] to the first nConstructed elements
//if tuple has 3 elements pop it and add it to result
for (int t = 0; t < nConstructed; ++t)
{
Triplet *first = constructed.front();
first->push_back(arr[i]);
if (first->size() == 3)
{
triplets.push_back(first); //if triplet is completed add it to triplets
}
else
{
constructed.push_back(first); //otherwise keep it in constructed
}
constructed.pop_front();
}
}
}
int main()
{
int * arr = new int[7] { 1, 1, 2, 2, 3, 4, 5 };
vector<Triplet*> triplets;
countTriplets(arr, 7, triplets);
for (auto triplet : triplets)
{
cout << "{ ";
for (int i : *triplet)
{
cout << i << " ";
}
cout << "} ";
delete triplet;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8ZGVxdWU+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovKgpsZXZlbCAxID0gMyB1bmlxdWU6IHsxLDIsM30gPSAxIHR1cGxlCmxldmVsIDIgPSA0IHVuaXF1ZTogezEsMiwzfSB7MSwyLDR9ICsgezEsMyw0fSArIDEgPSAzICsgMSA9IDQgdHVwbGVzCmxldmVsIDMgPSA1IHVuaXF1ZTogezEsMiwzfSB7MSwyLDR9IHsxLDIsNX0gKyB7MSwzLDR9IHsxLDMsNX0gKyB7MSw0LDV9ICsgNCA9IDEwIHR1cGxlcwpsZXZlbCA0ID0gNiB1bmlxdWU6IHsxLDIsM30gezEsMiw0fSB7MSwyLDV9IHsxLDIsNn0gKyB7MSwzLDR9IHsxLDMsNX0gezEsMyw2fSB7MSw0LDV9IHsxLDQsNn0gezEsNSw2fSArIDEwID0gMjAKKi8KCnR5cGVkZWYgdmVjdG9yPGludD4gVHJpcGxldDsKCmludCBnZXRTdW1TZXF1ZW5jZShpbnQgbikKewoJaWYgKG4gPD0gMCkKCQlyZXR1cm4gMDsKCglyZXR1cm4gbiArIGdldFN1bVNlcXVlbmNlKG4gLSAxKTsKfQoKaW50IGNvdW50VHJpcGxldHMoaW50IGluZGV4LCBpbnQgdW5pcXVlKQp7CglpbnQgbGV2ZWwgPSB1bmlxdWUgLSBpbmRleCAgLSAyOwoKCWlmIChsZXZlbCA8IDEpCgkJcmV0dXJuIDA7CgoJaWYgKGxldmVsID09IDEpCgkJcmV0dXJuIDE7CgoJcmV0dXJuIGdldFN1bVNlcXVlbmNlKGxldmVsKTsKfQoKLy9CRlMgYXBwcm9hY2gKdm9pZCBjb3VudFRyaXBsZXRzKGNvbnN0IGludCAqIGFyciwgaW50IGxlbmd0aCwgdmVjdG9yPFRyaXBsZXQqPiYgdHJpcGxldHMpCnsKCS8vZmlyc3QgY291bnQgbnVtYmVyIG9mIHVuaXF1ZSBlbGVtZW50cyB0byBhdm9pZCBkdXBsaWNhdGVzCglpbnQgdW5pcXVlID0gMTsKCWZvciAoaW50IGkgPSAxOyBpIDwgbGVuZ3RoOyArK2kpCgl7CgkJaWYgKGFycltpIC0gMV0gIT0gYXJyW2ldKQoJCQl1bmlxdWUrKzsKCX0KCglkZXF1ZTxUcmlwbGV0Kj4gY29uc3RydWN0ZWQ7CgkKCWludCBuQ29uc3RydWN0ZWQgPSBjb3VudFRyaXBsZXRzKDAsIHVuaXF1ZSk7CglpbnQgZWxlbWVudElEID0gMDsKCglmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgKytpKQoJewoJCS8vc2tpcCBkb3VibGVzCgkJaWYgKGkgPiAwICYmIGFycltpIC0gMV0gPT0gYXJyW2ldKQoJCQljb250aW51ZTsJCQoKCQkvL0FkZCBuZXcgdHVwbGVzIHRvIGRlcXVlIG9uIHRoaXMgbGV2ZWwKCQlpbnQgblRyaXBsZXRzID0gY291bnRUcmlwbGV0cyhlbGVtZW50SUQrKywgdW5pcXVlKTsKCQlmb3IgKGludCB0ID0gMDsgdCA8IG5UcmlwbGV0czsgKyt0KQoJCXsKCQkJVHJpcGxldCAqdHJpcGxldCA9IG5ldyBUcmlwbGV0KCk7CgkJCWNvbnN0cnVjdGVkLnB1c2hfZnJvbnQodHJpcGxldCk7CgkJfQoKCQkvL1Byb2Nlc3MgZXhpc3RpbmcgdHVwbGVzIGluIGRlcXVlIGJ5IGFkZGluZyBhcnJbaV0gdG8gdGhlIGZpcnN0IG5Db25zdHJ1Y3RlZCBlbGVtZW50cwoJCS8vaWYgdHVwbGUgaGFzIDMgZWxlbWVudHMgcG9wIGl0IGFuZCBhZGQgaXQgdG8gcmVzdWx0CgkJZm9yIChpbnQgdCA9IDA7IHQgPCBuQ29uc3RydWN0ZWQ7ICsrdCkKCQl7CgkJCVRyaXBsZXQgKmZpcnN0ID0gY29uc3RydWN0ZWQuZnJvbnQoKTsKCgkJCWZpcnN0LT5wdXNoX2JhY2soYXJyW2ldKTsKCQkJaWYgKGZpcnN0LT5zaXplKCkgPT0gMykKCQkJewoJCQkJdHJpcGxldHMucHVzaF9iYWNrKGZpcnN0KTsgLy9pZiB0cmlwbGV0IGlzIGNvbXBsZXRlZCBhZGQgaXQgdG8gdHJpcGxldHMKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWNvbnN0cnVjdGVkLnB1c2hfYmFjayhmaXJzdCk7IC8vb3RoZXJ3aXNlIGtlZXAgaXQgaW4gY29uc3RydWN0ZWQKCQkJfQoJCQljb25zdHJ1Y3RlZC5wb3BfZnJvbnQoKTsKCQl9Cgl9Cn0KCmludCBtYWluKCkKewoJaW50ICogYXJyID0gbmV3IGludFs3XSB7IDEsIDEsIDIsIDIsIDMsIDQsIDUgfTsKCXZlY3RvcjxUcmlwbGV0Kj4gdHJpcGxldHM7Cgljb3VudFRyaXBsZXRzKGFyciwgNywgdHJpcGxldHMpOwoKCWZvciAoYXV0byB0cmlwbGV0IDogdHJpcGxldHMpCgl7CgkJY291dCA8PCAieyAiOwoJCWZvciAoaW50IGkgOiAqdHJpcGxldCkKCQl7CgkJCWNvdXQgPDwgaSA8PCAiICI7CgkJfQoJCWNvdXQgPDwgIn0gIjsKCgkJZGVsZXRlIHRyaXBsZXQ7Cgl9CgkKCXJldHVybiAwOwp9