Project Euler #65: Convergents of e

Sort by

recency

|

13 Discussions

|

  • + 0 comments

    For a full explanation consider Project Euler 65

    import sys
    sys.set_int_max_str_digits(0)  # Remove the 4300 digit limit
    
    nx, ny = 1, 2
    for i in range(2, int(input())+1):
        m = 2*i//3 if i%3==0 else 1
        nx, ny = ny, nx + ny*m
    
    print (sum(map(int, str(ny))))
    
  • + 0 comments

    Python 3 solution, using the fact that the continued fraction of e has a pattern of 2 1 1 4 1 1 6 11, ..., from index 2:

    N = int(input())
    
    from math import e
    
    n0, n1 = 1, 2
    t = 1
    
    for i in range(1, N):
        n0, n1 = n1, n0 + t*n1
        t = 1 if (i - 1) % 3 != 0 else ((i - 1) // 3 + 1) * 2
        
    print(sum(map(int, str(n1))))
    
  • + 0 comments

    python solution

    from math import isqrt
    
    num, den, two = 1, 1, 2
    
    def sum_of_digits(n):
        s = 0
        while n:
            s, n = s + n % 10, n // 10
        return s
    
    def reciprocal():
        global num, den
        num, den = den, num
    
    def add_number_to_fraction(x):
        global num
        num = den * x + num
    
    g = int(input())
    if g == 1:
        print(2)
    elif g == 2:
        print(3)
    else:
        given = g
        three = 3
        num = (given // three) * two
        a = num - two
        if given % three == 1:
            num += 1
        elif given % three == 2:
            num = num * 2 + 1
            den = 2
        given -= given % three
        reciprocal()
        while given > 3:
            if given % three != 1:
                add_number_to_fraction(1)
            else:
                add_number_to_fraction(a)
                a -= two
            reciprocal()
            given -= 1
        add_number_to_fraction(1)
        reciprocal()
        add_number_to_fraction(2)
        print(sum_of_digits(num))
    
  • + 1 comment

    Java BigInteger

    Observed patterns how the fraction changes from the required convergent to back to 3rd convergent.

    I handle the 1st and 2nd convergents explicitly. I represent the fraction using two variables num and den which stand for numerator and denominator.

    First, I find out which multiple of 2 in the series is the closest to the required convergent. for example, if the required convergent is 10, then I make the fraction ready for calculation from '6' in the series. The variable a denotes the next multiple of 2 coming up in the series. for example, the fraction i prepared for convergent 10 was built using '6', but the next multiple of 2 in the series will be 4, so I assign a as '4'. I also made two functions, one: to "add an upcoming number" (whether 'a' or 1) to the fraction and two: to find the "reciprocal" of the fraction and then dividing the reciprocal by 1. (swapping num and den) The rest is pretty much self explanatory

    This was my code when I thought long would be enough:

    long num, den=1;
    private void driver(){
        int given = new Scanner(System.in).nextInt();
        if(given==1){
            System.out.println(2);
            return;
        }
        else if(given==2){
            System.out.println(3);
            return;
        }
        num = (given/3)*2;
        long a = num-2;
        if(given%3==1){
            num++;
        }else if(given%3==2){
            num = 2*num + 1;
            den = 2;
        }
        given -= given%3;
        reciprocal();
        while(given>3){
            if(given%3!=1)
                addNumberToFraction(1);
            else {
                addNumberToFraction(a);
                a -= 2;
            }
            reciprocal();
            given--;
        }
        addNumberToFraction(1);
        reciprocal();
        addNumberToFraction(2);
        System.out.println(sumOfDigits(num));
    }
    
    private long sumOfDigits(long num) {
        long sum = 0;
        while(num>0){
            sum += num%10;
            num /= 10;
        }
        return sum;
    }
    
    private void reciprocal(){
        long t = num;
        num = den;
        den = t;
    }
    
    private void addNumberToFraction(long x){
        num = den*x + num;
    }
    
      public static void main(String[] args) {
            new Question65().driver();
        }
    

    But obviously that did not work out as the numbers go way crazy! Then i converted the above same logic into BigInteger. Here it is:

    static BigInteger num, den = BigInteger.ONE, two = BigInteger.valueOf(2);
    
    public static void main(String[] args) {
        int g = new Scanner(System.in).nextInt();
        if(g==1){
            System.out.println(2);
            return;
        }
        else if(g==2){
            System.out.println(3);
            return;
        }
        BigInteger given = new BigInteger(g+"");
        BigInteger three = BigInteger.valueOf(3);
        num = (given.divide(three)).multiply(two);
        BigInteger a = num.subtract(two);
        if (given.mod(three).equals(BigInteger.ONE)) {
            num = num.add(BigInteger.ONE);
        } else if (given.mod(three).equals(two)) {
            num = num.multiply(two).add(BigInteger.ONE);
            den = two;
        }
        given = given.subtract(given.mod(three));
        reciprocal();
        while (given.compareTo(three) > 0) {
            if (!given.mod(three).equals(BigInteger.ONE))
                addNumberToFraction(BigInteger.ONE);
            else {
                addNumberToFraction(a);
                a = a.subtract(two);
            }
            reciprocal();
            given = given.subtract(BigInteger.ONE);
        }
        addNumberToFraction(BigInteger.ONE);
        reciprocal();
        addNumberToFraction(two);
        System.out.println(sumOfDigits(num));
    }
    
    private static BigInteger sumOfDigits(BigInteger num) {
        BigInteger sum = BigInteger.ZERO;
        while (num.compareTo(BigInteger.ZERO) > 0) {
            sum = sum.add(num.mod(BigInteger.TEN));
            num = num.divide(BigInteger.TEN);
        }
        return sum;
    }
    
    private static void reciprocal() {
        BigInteger t = num;
        num = den;
        den = t;
    }
    
    private static void addNumberToFraction(BigInteger x) {
        num = den.multiply(x).add(num);
    }
    

    Drop any queries in the comments, thanks ^__^

  • + 0 comments

    easiest one, read out https://en.wikipedia.org/wiki/Continued_fraction Hope you will find an interseting sequence :)