Greedy algorithm for Egyptian fractions: Difference between revisions
Content added Content deleted
m (C++ solution writes out numerator and denominator for Egyptian fractions with most terms/largest denominator) |
|||
Line 202: | Line 202: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
The C++ standard library does not have a "big integer" type, so this solution uses the Boost library. |
The C++ standard library does not have a "big integer" type, so this solution uses the Boost library. |
||
<lang cpp>#include <iostream> |
<lang cpp><lang cpp>#include <iostream> |
||
#include <vector> |
#include <vector> |
||
#include <algorithm> |
|||
#include <string> |
#include <string> |
||
#include <sstream> |
#include <sstream> |
||
#include <set> |
|||
#include <boost/multiprecision/cpp_int.hpp> |
#include <boost/multiprecision/cpp_int.hpp> |
||
typedef boost::multiprecision::cpp_int integer; |
typedef boost::multiprecision::cpp_int integer; |
||
struct rational |
|||
{ |
|||
integer numerator_; |
|||
integer denominator_; |
|||
rational(const integer& n, const integer& d) : numerator_(n), denominator_(d) |
|||
{ |
|||
} |
|||
⚫ | |||
std::ostream& operator<<(std::ostream& os, const rational& r) |
|||
{ |
|||
os << r.numerator_ << '/' << r.denominator_; |
|||
return os; |
|||
} |
|||
bool operator<(const rational& a, const rational& b) |
|||
{ |
|||
return a.numerator_ * b.denominator_ < b.numerator_ * a.denominator_; |
|||
} |
|||
integer mod(const integer& x, const integer& y) |
integer mod(const integer& x, const integer& y) |
||
Line 235: | Line 257: | ||
} |
} |
||
std::vector<integer> egyptian(integer x, integer y) |
|||
{ |
{ |
||
result |
std::vector<integer> result; |
||
while (x > 0) |
while (x > 0) |
||
{ |
{ |
||
Line 245: | Line 267: | ||
y = y * z; |
y = y * z; |
||
} |
} |
||
⚫ | |||
} |
} |
||
Line 266: | Line 289: | ||
x = x % y; |
x = x % y; |
||
} |
} |
||
std::vector<integer> result; |
std::vector<integer> result(egyptian(x ,y)); |
||
⚫ | |||
print_egyptian(result); |
print_egyptian(result); |
||
} |
} |
||
Line 274: | Line 296: | ||
{ |
{ |
||
size_t max_terms = 0; |
size_t max_terms = 0; |
||
integer max_terms_numerator, max_terms_denominator; |
|||
integer max_denominator_numerator, max_denominator_denominator; |
|||
std::vector<integer> max_terms_result; |
std::vector<integer> max_terms_result; |
||
integer max_denominator = 0; |
integer max_denominator = 0; |
||
std::vector<integer> max_denominator_result; |
std::vector<integer> max_denominator_result; |
||
std:: |
std::set<rational> fractions; |
||
for (integer b = 2; b < limit; ++b) |
for (integer b = 2; b < limit; ++b) |
||
{ |
{ |
||
for (integer a = 1; a < b; ++a) |
for (integer a = 1; a < b; ++a) |
||
{ |
{ |
||
rational r(a, b); |
|||
if (fractions.find(r) != fractions.end()) |
|||
continue; |
|||
fractions.insert(r); |
|||
std::vector<integer> result = egyptian(a, b); |
|||
if (result.size() > max_terms) |
if (result.size() > max_terms) |
||
{ |
{ |
||
max_terms = result.size(); |
max_terms = result.size(); |
||
max_terms_result = result; |
max_terms_result = result; |
||
max_terms_numerator = a; |
|||
max_terms_denominator = b; |
|||
} |
} |
||
integer largest_denominator = result.back(); |
integer largest_denominator = result.back(); |
||
Line 293: | Line 323: | ||
max_denominator = largest_denominator; |
max_denominator = largest_denominator; |
||
max_denominator_result = result; |
max_denominator_result = result; |
||
max_denominator_numerator = a; |
|||
max_denominator_denominator = b; |
|||
} |
} |
||
} |
} |
||
} |
} |
||
std::cout << "Proper fractions with most terms and largest denominator, limit = " << limit << ":\n\n"; |
std::cout << "Proper fractions with most terms and largest denominator, limit = " << limit << ":\n\n"; |
||
std::cout << "Most terms (" << max_terms << "): " |
std::cout << "Most terms (" << max_terms << "): " << max_terms_numerator |
||
<< '/' << max_terms_denominator << " = "; |
|||
print_egyptian(max_terms_result); |
print_egyptian(max_terms_result); |
||
std::cout << "Largest denominator (" << count_digits( |
std::cout << "Largest denominator (" << count_digits(max_denominator_result.back()) << " digits): " |
||
<< max_denominator_numerator << '/' << max_denominator_denominator << " = "; |
|||
print_egyptian(max_denominator_result); |
print_egyptian(max_denominator_result); |
||
} |
} |
||
Line 311: | Line 345: | ||
show_max_terms_and_max_denominator(1000); |
show_max_terms_and_max_denominator(1000); |
||
return 0; |
return 0; |
||
⚫ | |||
⚫ | |||
⚫ | |||
{{out}} |
{{out}} |
||
<pre> |
|||
Egyptian fraction for 43/48: 1/2 + 1/3 + 1/16 |
|||
Egyptian fraction for 5/121: 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795...3418846225 |
Egyptian fraction for 5/121: 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795...3418846225 |
||
Line 322: | Line 357: | ||
Proper fractions with most terms and largest denominator, limit = 100: |
Proper fractions with most terms and largest denominator, limit = 100: |
||
Most terms (8): 1/2 + 1/4 + 1/13 + 1/307 + 1/120871 + 1/20453597227 + 1/6972493991...6783218655 + 1/1458470173...7836808420 |
Most terms (8): 44/53 = 1/2 + 1/4 + 1/13 + 1/307 + 1/120871 + 1/20453597227 + 1/6972493991...6783218655 + 1/1458470173...7836808420 |
||
Largest denominator (150 digits): 1/13 + 1/181 + 1/38041 + 1/1736503177 + 1/3769304102927363485 + 1/1894353789...8154430149 + 1/5382864419...4225813153 + 1/5795045870...3909789665 |
Largest denominator (150 digits): 8/97 = 1/13 + 1/181 + 1/38041 + 1/1736503177 + 1/3769304102927363485 + 1/1894353789...8154430149 + 1/5382864419...4225813153 + 1/5795045870...3909789665 |
||
Proper fractions with most terms and largest denominator, limit = 1000: |
Proper fractions with most terms and largest denominator, limit = 1000: |
||
Most terms (13): 1/2 + 1/4 + 1/19 + 1/379 + 1/159223 + 1/28520799973 + 1/9296411783...1338400861 + 1/1008271507...4174730681 + 1/1219933718...8484537833 + 1/1860297848...1025882029 + 1/4614277444...8874327093 + 1/3193733450...1456418881 + 1/2039986670...2410165441 |
Most terms (13): 641/796 = 1/2 + 1/4 + 1/19 + 1/379 + 1/159223 + 1/28520799973 + 1/9296411783...1338400861 + 1/1008271507...4174730681 + 1/1219933718...8484537833 + 1/1860297848...1025882029 + 1/4614277444...8874327093 + 1/3193733450...1456418881 + 1/2039986670...2410165441 |
||
⚫ | Largest denominator (2847 digits): 36/457 = 1/13 + 1/541 + 1/321409 + 1/114781617793 + 1/1482167225...0844346913 + 1/2510651068...4290086881 + 1/7353930250...3326272641 + 1/6489634815...7391865217 + 1/5264420004...5476206145 + 1/3695215730...1238141889 + 1/2048192894...4706590593 + 1/8390188268...5525592705 |
||
⚫ | |||
</pre> |
</pre> |
||