Problem #65 medium
Convergents of e
The square root of 2 can be written as an infinite continued fraction.
The infinite continued fraction can be written, , indicates that 2 repeats ad infinitum. In a similar way, .
It turns out that the sequence of partial values of continued fractions for square roots provide the best rational approximations. Let us consider the convergents for .
&1 + \dfrac{1}{2} &= \dfrac{3}{2} \\ &1 + \dfrac{1}{2 + \dfrac{1}{2}} &= \dfrac{7}{5}\\ &1 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2}}} &= \dfrac{17}{12}\\ &1 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2 + \dfrac{1}{2}}}} &= \dfrac{41}{29} \end{align}$$ Hence the sequence of the first ten convergents for $\sqrt{2}$ are: $$1, \dfrac{3}{2}, \dfrac{7}{5}, \dfrac{17}{12}, \dfrac{41}{29}, \dfrac{99}{70}, \dfrac{239}{169}, \dfrac{577}{408}, \dfrac{1393}{985}, \dfrac{3363}{2378}, ...$$ What is most surprising is that the important mathematical constant, $$e = [2; 1, 2, 1, 1, 4, 1, ... , 1, 2k, 1, ...]$$ The first ten terms in the sequence of convergents for $e$ are: $$2, 3, \dfrac{8}{3}, \dfrac{11}{4}, \dfrac{19}{7}, \dfrac{87}{32}, \dfrac{106}{39}, \dfrac{193}{71}, \dfrac{1264}{465}, \dfrac{1457}{536}, ...$$ The sum of digits in the numerator of the 10th convergent is 1 + 4 + 5 + 7 = 17. Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e.Implementations
#include <iostream>#include <string>#include <vector>#include <algorithm>
static std::string add_big(const std::string& a, const std::string& b) { std::string result; int carry = 0; int i = a.size() - 1; int j = b.size() - 1; while (i >= 0 || j >= 0 || carry) { int sum = carry; if (i >= 0) sum += a[i--] - '0'; if (j >= 0) sum += b[j--] - '0'; carry = sum / 10; result.push_back(sum % 10 + '0'); } std::reverse(result.begin(), result.end()); return result;}
static std::string multiply_big(const std::string& a, int b) { std::string result; int carry = 0; for (int i = a.size() - 1; i >= 0; --i) { int prod = (a[i] - '0') * b + carry; carry = prod / 10; result.push_back(prod % 10 + '0'); } while (carry) { result.push_back(carry % 10 + '0'); carry /= 10; } std::reverse(result.begin(), result.end()); return result;}
static int sum_digits_big(const std::string& s) { int sum = 0; for (char c : s) sum += c - '0'; return sum;}
int convergents_of_e() { std::vector<int> terms; terms.push_back(2); for (int k = 1; ; ++k) { terms.push_back(1); terms.push_back(2 * k); terms.push_back(1); if (terms.size() >= 101) break; } std::string h_prev2 = "0"; std::string h_prev1 = "1"; std::string k_prev2 = "1"; std::string k_prev1 = "0"; for (int i = 0; i < 100; ++i) { std::string h = add_big(multiply_big(h_prev1, terms[i]), h_prev2); std::string k = add_big(multiply_big(k_prev1, terms[i]), k_prev2); h_prev2 = h_prev1; h_prev1 = h; k_prev2 = k_prev1; k_prev1 = k; } return sum_digits_big(h_prev1);}
#if ! defined UNITTEST_MODEint main(int argc, char const *argv[]) { std::cout << convergents_of_e() << std::endl;}#endif // UNITTEST_MODE View on GitHub
O(N) time, O(N) space (due to string lengths)