#include <iostream>
using namespace std;
int pairFinder(int a[], int n, int target, int out[][2], int &uc, bool unique); // prototype
void printPairs(int out[][2], int m); // prototype
int main() {
int a[] = {2, 7, 4, 5, 3, 6, 3};
int n = sizeof(a) / sizeof(a[0]);
int target = 9;
int outAll[50][2];
int allCount = 0;
int mAll = pairFinder(a, n, target, outAll, allCount, false);
cout << "All pairs: ";
printPairs(outAll, mAll);
int outUnique[50][2];
int uniqueCount = 0;
int mUnique = pairFinder(a, n, target, outUnique, uniqueCount, true);
cout << "Unique-by-value pairs: ";
printPairs(outUnique, mUnique);
return 0;
}
int pairFinder(int a[], int n, int target, int out[][2], int &uc, bool unique) {
int w = 0;
// For uniqueness tracking we store unordered pairs as two adjacent slots in seenVals
int seenVals[100]; // enough room for pairs (2 slots per stored pair)
int sc = 0; // number of used slots in seenVals
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] + a[j] == target) {
bool already = false;
if (unique) {
// check stored pairs (each pair occupies two slots)
for (int t = 0; t + 1 < sc; t += 2) {
int x = seenVals[t];
int y = seenVals[t + 1];
if ((x == a[i] && y == a[j]) || (x == a[j] && y == a[i])) {
already = true;
break;
}
}
}
if (!already) {
out[w][0] = a[i];
out[w][1] = a[j];
w++;
if (unique) {
// append unordered pair to seenVals
seenVals[sc++] = a[i];
seenVals[sc++] = a[j];
}
}
}
}
}
uc = w;
return w;
}
void printPairs(int out[][2], int m) {
if (m == 0) {
cout << "None\n";
return;
}
for (int i = 0; i < m; i++) {
cout << "(" << out[i][0] << "," << out[i][1] << ")" << (i + 1 < m ? " " : "\n");
}
}

