1. 程式人生 > >Project Euler Problem 57 (C++和Python)

Project Euler Problem 57 (C++和Python)

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()