78 lines
2.1 KiB
C++
78 lines
2.1 KiB
C++
// Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.
|
|
// Probably good to know that e can be written as [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, ..., 1, 2k, 1, ...]
|
|
|
|
#include <bits/stdc++.h>
|
|
#include "../bigint.h"
|
|
|
|
using namespace std;
|
|
|
|
InfInt gcd(InfInt a, InfInt b){
|
|
if(b == 0){
|
|
return a;
|
|
}
|
|
return gcd(b, a % b);
|
|
}
|
|
|
|
pair<InfInt, InfInt> fracAdd(const pair<InfInt, InfInt>& f1, const pair<InfInt, InfInt>& f2){
|
|
pair<InfInt, InfInt> result = {f1.first*f2.second + f2.first*f1.second, f1.second * f2.second};
|
|
InfInt g = gcd(result.first, result.second);
|
|
|
|
result.first /= g;
|
|
result.second /= g;
|
|
|
|
return result;
|
|
}
|
|
|
|
pair<InfInt, InfInt> fracInv(const pair<InfInt, InfInt>& f){
|
|
return pair<InfInt, InfInt>(f.second, f.first);
|
|
}
|
|
|
|
pair<InfInt, InfInt> cfApprox(const vector<int>& seq){
|
|
pair<InfInt, InfInt> result = {seq[0], 1};
|
|
pair<InfInt, InfInt> carry = {0, 1};
|
|
if(seq.size() > 1){
|
|
carry = {1, seq[1]};
|
|
for(size_t i = seq.size() - 2; i > 0; --i){
|
|
pair<InfInt, InfInt> newp = {seq[i], 1};
|
|
carry = fracInv(fracAdd(carry, newp));
|
|
}
|
|
}
|
|
|
|
result = fracAdd(result, carry);
|
|
|
|
return result;
|
|
}
|
|
|
|
int main(){
|
|
|
|
cout << "HeInfInto this is Patrick" << endl;
|
|
auto start = chrono::high_resolution_clock::now();
|
|
|
|
// Generate the e sequence
|
|
vector<int> seq;
|
|
seq.push_back(2);
|
|
for(int i = 0; i < 99; ++i){
|
|
if(i % 3 == 0 || i % 3 == 2){
|
|
seq.push_back(1);
|
|
} else{
|
|
seq.push_back(((i / 3) + 1) * 2);
|
|
}
|
|
}
|
|
|
|
auto f = cfApprox(seq);
|
|
InfInt frac = f.first;
|
|
InfInt result = 0;
|
|
|
|
while(frac > 0){
|
|
result += frac % 10;
|
|
frac /= 10;
|
|
}
|
|
|
|
cout << "Fraction of " << f.first << " / " << f.second << " resulting in sum of: ";
|
|
cout << result << endl;
|
|
|
|
auto duration = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start);
|
|
cout << (float)duration.count()/1000 << endl;
|
|
return 0;
|
|
}
|