Project Euler #2: Even Fibonacci numbers

  • + 21 comments

    Notice That:: Every third term of this series is even.... and the series of even terms goes like 0,2,8,34,... so any even term E(n)can be expressed as E(n)= 4*E(n-1) + E(n-2)....

    this small knowledge makes the algorithm quite small and effective.

    • + 7 comments

      Hi dude, I have implemented the idea you have said in C++. I am getting 2nd 3rd cases time limit exceeded. Could you suggest me where I am going wrong. https://ideone.com/0shXEY

      • + 3 comments

        I've just copied my code from C++ and changed it to Java (used long instead of long long int) and it works like a charm!

        • + 0 comments

          Same worked for me! thanks

        • + 1 comment

          It's working for me also, But what's the logic behind this?

          • [deleted]
            + 1 comment

            Most easy solution in Java & it passes all the test cases:

            public class Solution {

            public static void main(String[] args) {
                Scanner in = new Scanner(System.in);
                int t = in.nextInt();
                for(int a0 = 0; a0 < t; a0++){
                    long n = in.nextLong();
                    long first = 0, second = 1, sum =0, sumeven =0;
            
                    while(second <= n){
                        sum = first+second;
                        first = second;
                        second = sum; 
                        if(sum%2==0 && sum<n){
                            sumeven += sum;
                        }
                    }
                    System.out.println(sumeven);
                }
            }
            

            }

        • + 0 comments

          https://www.hackerrank.com/contests/projecteuler/challenges/euler002/forum/comments/1109726

      • + 0 comments

        every variable and function use long long and you could get it.

      • + 0 comments

        use unsigned long long int sum=0; long int f0 = 2; long int f1 = 8; long int f2

      • + 0 comments

        same dude, I solved using matrix exponentiation but still got WA

      • + 0 comments

        Change the parameter to long n, and its all right

      • + 0 comments

        You just gotta use long long and you'll get it. Don't know why all these people are downvoting you instead of just pointing it out.

    • + 1 comment
      [deleted]
      • + 1 comment

        did not get you...

        • + 0 comments

          Easy solution

          https://www.hackerrank.com/contests/projecteuler/challenges/euler002/forum/comments/557643

    • + 1 comment

      can you explain this a bit more with an example

      E(n)= 4*E(n-1) + E(n-2)....

      • + 1 comment

        if you check the series 0, 1, 2, 3, 5, 8 which is the fibinoacci series every third term is even and the next even term sequence can be caluclated using 4 * (8) + 2 which is 4*(n-3) + (n- 6)

        • + 0 comments

          [1, 1, 2, 3, 5, 8]

    • + 1 comment

      It can be derived using a few arithmetic transformations:

      F(n) = F(n-1) + F(n-2) = F(n-2) + F(n-3) + F(n-2)
      F(n) = 2F(n-2) + F(n-3)
      --This proves the point that every third term is even (if F(n-3) is even, then F(n) must be even too)
      
      F(n) = 2[F(n-3) + F(n-4)] + F(n-3)
      = 3F(n-3) + 2F(n-4)
      = 3F(n-3) + 2F(n-5) + 2F(n-6)
      
      From eq.1: 
      F(n-3) = 2F(n-5) + F(n-6)
      2F(n-5) = F(n-3) - F(n-6)
      
      F(n) = 3F(n-3) + [F(n-3) - F(n-6)] + 2F(n-6)
      = 4F(n-3) + F(n-6)
      

      If the sequence of even numbers consists of every third number (n, n-3, n-6, ...)

      E(k) = 4E(k-1) + E(k-2)
      
      • + 0 comments

        wow, the solution is so neat

    • + 4 comments

      This is an interesting observation. However I see no performance increase compared to traditional solution (f(n) = f(n - 2) + f(n - 1)).

      • + 2 comments

        Actually it does. One can skip few steps Using this formula one will get only the even fibinoacci numbers. Traditional algo will be :

        f1=1;

        f2=2;

        f=0;

        while(f1 less than n)

        {

        if(f%2==0) sum+=f;

        f=f1+f2;

        f2=f1;

        f1=f;

        }

        print -> sum

        However you can skip the step of verifing odd-even. Also you are skiping 2 odd number and directly getting only the even numbers.

        f1=2;

        f2=0;

        f=0;

        while(f1 less than n) {

        sum+=f1;

        f=4*f1+f2;

        f2=f1;

        f1=f;

        }

        print -> sum

        PS-Sorry for bad english

        • + 0 comments

          This does not change the time complexity from O(n) however.

          Orignal time is something like O(3n) -> O(n)

          New time complexity is something like O(2n/3) -> O(n)

        • + 2 comments
          #include <map>
          #include <set>
          #include <list>
          #include <cmath>
          #include <ctime>
          #include <deque>
          #include <queue>
          #include <stack>
          #include <string>
          #include <bitset>
          #include <cstdio>
          #include <limits>
          #include <vector>
          #include <climits>
          #include <cstring>
          #include <cstdlib>
          #include <fstream>
          #include <numeric>
          #include <sstream>
          #include <iostream>
          #include <algorithm>
          #include <unordered_map>
          
          using namespace std;
          
          
          int main(){
              int t;
              cin >> t;
              for(int a0 = 0; a0 < t; a0++){
                  long n;
                  cin >> n;
                  long long int f1 = 1,f2 = 2,f = 0, sum = 0;
                  while(f1 < n)
                  {
                      if(f1 % 2 == 0)
                      {
                          sum += f1;
                      }
                      f = f1 + f2;
                      f1 = f2;
                      f2 = f;
                      //cout << f1 << endl;
                  }
                  cout << sum << endl;
              }   return 0;
          }
          
          • + 1 comment

            LOL bro, why you've added those headers? ☻

            • + 1 comment

              is it working for testcase 2 and 3?? i guess not.

              • + 0 comments

                that code is working..do in c++ editor

          • + 0 comments

            wrong output

      • + 1 comment

        Well, test case #3 completed in less than half the time using this technique for me. Using Python 3.

        • + 0 comments

          what is tect case #3

      • + 1 comment

        Instead of recursion I used this formula and it should cut down complexity quite a bit, but I still get two timeouts, so not sure what my algo is doing to be so slow.

        Binet's Formula

        • + 1 comment

          The Binet's Formula would be very helpful in case we need to compute only n'th number.

          But to calculate sums we need all even numbers and recursive calculation "E(n) = 4E(n-1) + E(n-2)" of all even numbers would be faster then calculacting them by Binet's Formula.

          • + 0 comments

            Yes That will be a great

      • + 0 comments

        the observation reduce computation by 66%, as two loop cycles each round are skipped including the computation

    • + 0 comments

      Because of the growth of the sequence the difference in time complexity observed here seems irrelevant compared to that of the standard equation, even for massive values...

    • + 5 comments
      long long fiboEven(long long N) {
          if(N==1){
              return 2;
          } else if(N==2){
              return 8;
          } else {
              return 4*((fiboEven(N-1)))+fiboEven(N-2);
          }
      }
      long long addFibo(long long N){
          long long sum=0,i;
              for(i=1;i<=N;i++){
                  if(fiboEven(i)<=N){
                      sum=sum + fiboEven(i);
                  } else
                  break;
              }
          return sum;
      }
      

      Getting error in Test Case #3

      • + 0 comments

        Same :/

      • + 0 comments

        same -_-

      • + 0 comments

        The problem here is that your fiboAdd has too many unnecessary calculations:

        1. The most serious offender is the fiboEven function. Let's say you calculate fiboEven(10), you recursively call fiboEven(9) and fiboEven(8) but the whole recursive subtree rooted at fiboEven(8) is contained in fiboEven(9). You need memoization. This is the same reasoning as the standard reasoning for why it's good to have memoization for recursive fibonacci series calculation. You don't want a recursion tree (with branching factor a=2) if you can effectively get a recursion list (with branching factor a=1).

        2. The successive fiboEven(i) calls in addFibo(N) are also redundant with the recursion tree for i+1 going through recursion tree for i, even though you just went through it in the previous outer fiboEven call. You need to keep track of the previously calculated fiboEven(i-1) to quickly calculate fiboEven(i).

        3. Also, for each i you call fiboEven(i) in fiboAdd twice: inside if statement and on the next line. So, you can cut you workload in half by saving the result in a variable and reusing.

        Personally, I think (bottom-up) iterative approach is a better fit here because you don't need any memoization you just keep the previous fiboEven number, the current fiboEven number and the current sum in memory and that's it.

      • + 0 comments

        Try to do precalculation and store it in list. You will get it

      • + 0 comments

        if(fiboEven(i)<=N) so if it is == N then it will still add fiboEven making it larger than N.

    • + 1 comment

      Bro you and Dan Brown made it possible for me to solve this problem. Only test case 3 is always returning wrong. Can you help me? (Note: I am new to programming, sorry for any noobish mistake)

      golden = (1 + 5 ** 0.5) / 2
      phi3 = golden**3
      T = int(input().strip())
      for i in range(T):
          N = int(input().strip())
          n = 2
          sum = 0
          while n < N:
              sum += n
              n = int(phi3 * n + 0.5)            
          print(sum)
      
      • + 0 comments

        Thank you so much. I finally passed.

    • + 0 comments

      Thanks for your Idea, finally get it passed using JS A_A

    • + 0 comments

      This is not required. Fibonacci sequence grows very fast. 4*10^16 can be reached in less than 80 iterations.

    • + 0 comments

      just read about it Benit Theorem on fabonacci serious, & start the current num = 2; curr_num = int(pow(((1 + pow(5 , 0.5)) / 2),3) * curr_num + 0.5)

    • + 2 comments

      I used Binet's formula, changed to long in C++ and I still get a few timeouts. Any recommendations?

      • + 0 comments

        well this won't give any timeouts but one test case is failing , i think it's because of inaccuracy we get in golden ratio while calculating it for very large term for e.g. the following code will generate 27th term as 37889062373143904 instead of 37889062373143906. rectify it and you will get the correct code :)

        int main(){
            int t; 
            scanf("%d",&t);
            for(int a0 = 0; a0 < t; a0++){
                long n, sum = 0; 
                scanf("%ld",&n);
                long curr_num = 2;
                while(curr_num<=n){
                    sum += curr_num;
                    curr_num = (long)floor((pow(((1 + pow(5 , 0.5)) / 2),3) * curr_num + 0.5));
                    //sum += curr_num;
                }
                printf("%ld \n", sum);
            }
            return 0;
        }
        
      • + 1 comment

        sorry for late advice - store the first fibbonachi numbers in memory and go thrue tests $-)

        import functools
        @functools.lru_cache(maxsize=None)
        def fib(n):
            if n<=2:
                return 1
            else:
                return fib(n-1) + fib(n-2)
        
        
        
        n = int(input().strip())
        s=0
        for i in range(3,n,3):
            _ = fib(i)
            if _<=n:
                s+=_
            else:
                break
                
        print(_)
        

        all works on slow but wise Python

        • + 0 comments

          for i in range(3,n,3) I see what you did there, smart.

    • + 0 comments
      s = 0
      big = 2
      pre = 0
      while big < n:
          n_e = big*4 + pre 
          s += big
          pre = big
          big = n_e
      print(s)
      
    • + 0 comments

      C++ implementation using this algorithm!

      long total = 0;
      long previous = 0;        
      long current = 2;        
      while(current < n) {  
      	total += current;          
      	long aux = current;
      	current = current * 4 + previous;
      	previous = aux;
      }
      cout << total << "\n";
      
    • + 0 comments

      super thought .....

      salute */*

    • + 0 comments

      Thank you for the help.

    • + 0 comments

      It worked for me and I implemented this summation in python 3. https://www.hackerrank.com/contests/projecteuler/challenges/euler002/submissions/code/1315739685

    • + 2 comments

      Your post was the most helpful.

      I'm just wondering why no one has posted an ACTUAL answer to this problem in over 4 years.

      Which means

      is the solution to it. Now the trick is to find a fast way to compute what n might actually be .

      • + 0 comments

        Fibonacci_index

        It's not perfect. When k = 12, n = 7. However, the n-th term for F is 13. We can check agaisnt this quickly with the same formula going forwards and backwards ONCE. instead of over a loop like everyone has been doing.

        I should mention the relationship I gues. F_0 = 0, E = F_{3n}

      • + 0 comments

        I should mention, all this is useless past a certain point on a computer since percision is slowly lost. However, NASA has a great article on how accurate pi needs to be.

    • + 0 comments

      Easiest Solution with all test cases passing. t = int(input().strip()) for a0 in range(t): n = int(input().strip()) t1=1 t2=2 temp=2 t3=0 while(True): t3=t1+t2 t1,t2=t2,t3 if(t3>n): break if(t3%2==0): temp+=t3 print(temp)

    • + 0 comments

      @dusty_mehul the series you gave is wrong. For example- the term 144(after 34) cant be expressed as 4*34 +8+2+0 because this is equal to 146 not 144!!