Project Euler Problem 57 (C++和Python)
阿新 • • 發佈:2018-12-26
Problem 57 : Square root convergents
It is possible to show that the square root of two can be expressed as an infinite continued fraction.
√ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + … ))) = 1.414213…
By expanding this for the first four iterations, we get:
1 + 1/2 = 3/2 = 1.5
1 + 1/(2 + 1/2) = 7/5 = 1.4
1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666…
1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379…
The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.
In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?
C++程式碼
#include <iostream>
#include <vector>
#include <iterator>
#include <cassert>
using namespace std;
//#define UNIT_TEST
class PE0057
{
private:
vector<int> getNewNumerator(vector<int>& tmp_den_vec,
int multiple, vector<int>& tmp_num_vec);
public:
int getNumberOfFractions(int expansions);
};
vector<int> PE0057::getNewNumerator(vector<int>& tmp_den_vec,
int multiple, vector<int>& tmp_num_vec)
{
int size_d = tmp_den_vec.size();
int size_n = tmp_num_vec.size();
vector<int> new_num_vec;
if (size_d > size_n)
{
for(int i=0; i<size_n; i++)
{
new_num_vec.push_back(multiple*tmp_den_vec[i] + tmp_num_vec[i]);
}
for(int i=size_n; i<size_d; i++)
{
new_num_vec.push_back(multiple*tmp_den_vec[i]);
}
}
else if(size_d < size_n)
{
for(int i=0; i<size_d; i++)
{
new_num_vec.push_back(multiple*tmp_den_vec[i] + tmp_num_vec[i]);
}
for(int i=size_d; i<size_n; i++)
{
new_num_vec.push_back(multiple*tmp_den_vec[i]);
}
}
else if (size_d == size_n)
{
for(int i=0; i<size_n; i++)
{
new_num_vec.push_back(multiple*tmp_den_vec[i] + tmp_num_vec[i]);
}
}
int size_num = new_num_vec.size();
for(int i=0; i<size_num; i++)
{
if (new_num_vec[i] >= 10 )
{
if (i==size_num-1)
{
new_num_vec.push_back(new_num_vec[i] / 10);
}
else
{
new_num_vec[i+1] += new_num_vec[i] / 10;
}
new_num_vec[i] %= 10;
}
}
return new_num_vec;
}
int PE0057::getNumberOfFractions(int expansions)
{
int numOfFractions = 0;
vector<int> num_vec; // new numerator digits vector
vector<int> den_vec; // new denominator digits vector
vector<int> tmp_num_vec; // temporary numerator digits vector
vector<int> tmp_den_vec; // temporary denominator digits vector
tmp_num_vec.push_back(0); // initial numerator value 0
tmp_den_vec.push_back(1); // initial denominator value 1
for (int i=1; i<=expansions; i++)
{
// num_vec/den_vec = 2 + tmp_num_vec/tmp_den_vec
// = (2*tmp_den_vec + tmp_num_vec)/tmp_den_vec
// num_vec = 2*tmp_den_vec + tmp_num_vec
// den_vec = tmp_den_vec
num_vec = getNewNumerator(tmp_den_vec, 2, tmp_num_vec);
den_vec = tmp_den_vec;
// change num_vec/den_vec to tmp_den_vec/tmp_num_vec
tmp_den_vec = num_vec;
tmp_num_vec = den_vec;
// num_vec/den_vec = 1 + tmp_num_vec/tmp_den_vec
// = (tmp_den_vec + tmp_num_vec)/tmp_den_vec
// num_vec = tmp_den_vec + tmp_num_vec
// den_vec = tmp_den_vec
num_vec = getNewNumerator(tmp_den_vec, 1, tmp_num_vec);
den_vec = tmp_den_vec;
#ifdef UNIT_TEST
if (i > expansions - 2)
{
cout << i << "th expansion, numerator: " ;
copy(num_vec.rbegin(), num_vec.rend(),ostream_iterator<int>(cout));
cout << "(" << num_vec.size() << ")" << " denominator : ";
copy(den_vec.rbegin(), den_vec.rend(),ostream_iterator<int>(cout));
cout << "(" << den_vec.size() << ")" << endl;
}
#endif
if (num_vec.size() > den_vec.size())
{
numOfFractions ++;
}
}
return numOfFractions;
}
int main()
{
PE0057 pe0057;
assert (1 == pe0057.getNumberOfFractions(8));
int numOfFractions = pe0057.getNumberOfFractions(1000);
cout << "In the first one-thousand expansions, ";
cout << numOfFractions << " fractions " << endl;
cout << "contain a numerator with more digits than denominator" << endl;
return 0;
}
Python 程式碼
def getNumberOfFractions(expansions):
numOfFractions, numerator, denominator = 0, 1, 1
for i in range(1, expansions+1):
numerator, denominator = 2*denominator+numerator, denominator+numerator
#if i > expansions - 2:
# print("%dth"%i,"expansion, numerator: ", numerator, end='')
# print("(", len(str(numerator)), ") denominator : ", end='')
# print(denominator, "(", len(str(denominator)), ")")
if len(str(numerator)) > len(str(denominator)):
numOfFractions += 1
return numOfFractions
def main():
assert 1 == getNumberOfFractions(8)
numOfFractions = getNumberOfFractions(1000)
print("In the first one-thousand expansions,",numOfFractions,end=' ')
print("fractions\ncontain a nuerator with more digits than denominator.")
if __name__ == '__main__':
main()