#include #include #include #include using namespace std; struct Numbers { int a, b; bool operator< (const Numbers &other) const { if (a != other.a) return a < other.a; return b < other.b; } }; typedef set Possibilities; void verbose(const string &role, const Possibilities &possibilities) { cout << role << ": "; if (possibilities.empty()) { cout << "No solutions." << endl; } else if (possibilities.size() == 1) { Possibilities::const_iterator i = possibilities.begin(); Numbers n = *i; cout << "Solution is " << n.a << "," << n.b << "." << endl; } else { cout << "Possibilities are"; for (Possibilities::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i) { cout << " " << (*i).a << "," << (*i).b; } cout << "." << endl; } } void productVerbose(const Possibilities &possibilities) { verbose("Product", possibilities); } void sumVerbose(const Possibilities &possibilities) { verbose("Sum", possibilities); } bool answer1(int product, int limit, Possibilities &possibilities, bool verbose = false) { Numbers n; possibilities.clear(); for (n.a = 2; n.a <= limit; ++n.a) { n.b = product/n.a; if (n.b < n.a) { break; } if (n.b <= limit && n.a*n.b == product) { possibilities.insert(n); } } if (verbose) { productVerbose(possibilities); } return possibilities.size() > 1; } bool answer2(int sum, int limit, Possibilities &possibilities, bool verbose = false) { Numbers n; possibilities.clear(); for (n.a = 2; n.a <= limit; ++n.a) { n.b = sum - n.a; if (n.b < n.a) { break; } if (n.b <= limit) { possibilities.insert(n); } } if (possibilities.size() <= 1) { if (verbose) { sumVerbose(possibilities); } return false; } for (Possibilities::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i) { Possibilities tmp; if (answer1((*i).a*(*i).b, limit, tmp) == false) { if (verbose) { cout << "Sum: Product can factorize " << (*i).a << "*" << (*i).b << "."<< endl; } return false; } } if (verbose) { sumVerbose(possibilities); } return true; } bool answer3(int product, int limit, Possibilities &possibilities, bool verbose = false) { if (answer1(product, limit, possibilities) == false) { return false; } Possibilities toErase; for (Possibilities::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i) { Possibilities tmp; if (answer2((*i).a + (*i).b, limit, tmp) == false) { toErase.insert(*i); } } for (Possibilities::const_iterator i = toErase.begin(); i != toErase.end(); ++i) { possibilities.erase(*i); } if (verbose) { productVerbose(possibilities); } return possibilities.size() == 1; } bool answer4(int sum, int limit, Possibilities &possibilities, bool verbose = false) { if (answer2(sum, limit, possibilities) == false) { return false; } Possibilities toErase; for (Possibilities::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i) { Possibilities tmp; if (answer3((*i).a*(*i).b, limit, tmp) == false) { toErase.insert(*i); } } for (Possibilities::const_iterator i = toErase.begin(); i != toErase.end(); ++i) { possibilities.erase(*i); } if (verbose) { sumVerbose(possibilities); } return possibilities.size() == 1; } bool solver(int limit, Possibilities &possibilities) { cout << "Solving for limit " << limit << "." << endl; possibilities.clear(); for (int a = 2; a <= limit; ++a) { for (int b = a; b <= limit; ++b) { int product = a*b; int sum = a + b; Possibilities tmp; if (answer3(product, limit, tmp) && answer4(sum, limit, tmp)) { Numbers n; cout << a << "," << b << endl; if (possibilities.empty() == false) { return false; } n.a = a; n.b = b; possibilities.insert(n); } } } return possibilities.size() == 1; } void test(int a, int b, int limit) { cout << "Test for " << a << "," << b << " and limit " << limit << endl; if (limit < 2) { cout << "Limit must not be less than 2." << endl; return; } if (a < 2 || b < 2 || a > limit || b > limit) { cout << "Numbers must be in the range 2,...," << limit << "." << endl; return; } int product = a*b; int sum = a + b; Possibilities p; if (answer1(product, limit, p, true) && answer2(sum, limit, p, true) && answer3(product, limit, p, true) && answer4(sum, limit, p, true)) { cout << "This pair is possible." << endl; } else { cout << "This pair is not possible." << endl; } } void solve(int limit) { Possibilities tmp; solver(limit, tmp); } void solveAndTest(int limit) { Possibilities possibilities; solver(limit, possibilities); if (possibilities.empty()) { cout << "No solution for this limit." << endl; return; } if (possibilities.size() == 1) { Numbers numbers = *(possibilities.begin()); cout << "This is the unique solution for this limit.\n" << endl; test(numbers.a, numbers.b, limit); return; } cout << "The solution for this limit is not unique." << endl; for (Possibilities::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i) { cout << endl; test((*i).a, (*i).b, limit); } } int main() { solveAndTest(30); cout << endl; solveAndTest(200); return EXIT_SUCCESS; }