#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
#include <cmath>
namespace Chapter7
{
class Exercise3
{
public:
void Find(int lo, int hi, std::ostream& out = std::cout);
private:
std::vector<int> factors_;
bool IsPrime(int candidate);
void GetFactors(int candidate);
};
}
int main()
{
Chapter7::Exercise3 solver;
solver.Find(1, 1000);
}
void Chapter7::Exercise3::Find(int lo, int hi, std::ostream& out)
{
int sum;
for (int i = lo; i <= hi; ++i) {
GetFactors(i);
sum = std::accumulate(factors_.begin(), factors_.end(), 0);
if (IsPrime(sum)) {
out << std::setw(4) << i << ". ";
if (factors_.size() != 1) {
std::vector<int>::iterator elem = factors_.begin();
out << *elem;
for (++elem; elem < factors_.end(); ++elem) {
out << " + " << *elem;
}
out << " = " << sum;
}
out << std::endl;
}
}
}
bool Chapter7::Exercise3::IsPrime(int candidate)
{
if (candidate <= 1) return false; // candidate is not prime by definition
if (candidate == 2) return true;
if ((candidate & 1) == 0) return false; // even cadidate
double root = std::sqrt(candidate);
for (int i = 3; i <= root; i += 2) {
if (candidate % i == 0) {
return false;
}
}
return true;
}
void Chapter7::Exercise3::GetFactors(int candidate)
{
int i = 2;
factors_.clear();
while (candidate > 1) {
while (candidate % i == 0) {
factors_.push_back(i);
candidate /= i;
}
++i;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPG51bWVyaWM+CiNpbmNsdWRlIDxjbWF0aD4KCm5hbWVzcGFjZSBDaGFwdGVyNwp7CgljbGFzcyBFeGVyY2lzZTMKCXsKCQlwdWJsaWM6CgkJdm9pZCBGaW5kKGludCBsbywgaW50IGhpLCBzdGQ6Om9zdHJlYW0mIG91dCA9IHN0ZDo6Y291dCk7CgkJCgkJcHJpdmF0ZToKCQlzdGQ6OnZlY3RvcjxpbnQ+IGZhY3RvcnNfOwoJCWJvb2wgSXNQcmltZShpbnQgY2FuZGlkYXRlKTsKCQl2b2lkIEdldEZhY3RvcnMoaW50IGNhbmRpZGF0ZSk7Cgl9Owp9CgppbnQgbWFpbigpIAp7CglDaGFwdGVyNzo6RXhlcmNpc2UzIHNvbHZlcjsKCXNvbHZlci5GaW5kKDEsIDEwMDApOwp9Cgp2b2lkIENoYXB0ZXI3OjpFeGVyY2lzZTM6OkZpbmQoaW50IGxvLCBpbnQgaGksIHN0ZDo6b3N0cmVhbSYgb3V0KQp7CglpbnQgc3VtOwoJZm9yIChpbnQgaSA9IGxvOyBpIDw9IGhpOyArK2kpIHsKCQlHZXRGYWN0b3JzKGkpOwoJCXN1bSA9IHN0ZDo6YWNjdW11bGF0ZShmYWN0b3JzXy5iZWdpbigpLCBmYWN0b3JzXy5lbmQoKSwgMCk7CgkJaWYgKElzUHJpbWUoc3VtKSkgewoJCQlvdXQgPDwgc3RkOjpzZXR3KDQpIDw8IGkgPDwgIi4gIjsKCQkJaWYgKGZhY3RvcnNfLnNpemUoKSAhPSAxKSB7CgkJCQlzdGQ6OnZlY3RvcjxpbnQ+OjppdGVyYXRvciBlbGVtID0gZmFjdG9yc18uYmVnaW4oKTsKCQkJCW91dCA8PCAqZWxlbTsKCQkJCWZvciAoKytlbGVtOyBlbGVtIDwgZmFjdG9yc18uZW5kKCk7ICsrZWxlbSkgewoJCQkJCW91dCA8PCAiICsgIiA8PCAqZWxlbTsKCQkJCX0KCQkJCW91dCA8PCAiID0gIiA8PCBzdW07CgkJCX0KCQkJb3V0IDw8IHN0ZDo6ZW5kbDsKCQl9Cgl9Cn0KCmJvb2wgQ2hhcHRlcjc6OkV4ZXJjaXNlMzo6SXNQcmltZShpbnQgY2FuZGlkYXRlKQp7CglpZiAoY2FuZGlkYXRlIDw9IDEpIHJldHVybiBmYWxzZTsgLy8gY2FuZGlkYXRlIGlzIG5vdCBwcmltZSBieSBkZWZpbml0aW9uCglpZiAoY2FuZGlkYXRlID09IDIpIHJldHVybiB0cnVlOwoJaWYgKChjYW5kaWRhdGUgJiAxKSA9PSAwKSByZXR1cm4gZmFsc2U7IC8vIGV2ZW4gY2FkaWRhdGUKCQoJZG91YmxlIHJvb3QgPSBzdGQ6OnNxcnQoY2FuZGlkYXRlKTsKCWZvciAoaW50IGkgPSAzOyBpIDw9IHJvb3Q7IGkgKz0gMikgewoJCWlmIChjYW5kaWRhdGUgJSBpID09IDApIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KCXJldHVybiB0cnVlOwp9Cgp2b2lkIENoYXB0ZXI3OjpFeGVyY2lzZTM6OkdldEZhY3RvcnMoaW50IGNhbmRpZGF0ZSkKewoJaW50IGkgPSAyOwoJZmFjdG9yc18uY2xlYXIoKTsKCXdoaWxlIChjYW5kaWRhdGUgPiAxKSB7CgkJd2hpbGUgKGNhbmRpZGF0ZSAlIGkgPT0gMCkgewoJCQlmYWN0b3JzXy5wdXNoX2JhY2soaSk7CgkJCWNhbmRpZGF0ZSAvPSBpOwoJCX0KCQkrK2k7Cgl9Cn0K