-2

I am trying to find the last digit of sum of Fibonacci Series. I calculate the sum as F(n+2) - 1. The below code is working fine but it is slow for large numbers (e.g 99999). How can I optimize this?

n = int(input())

def last_digit(n):
    a, b = 0, 1
    for i in range(n+2):
        a, b = b, a + b
    return (a-1) % 10

print(last_digit(n))
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
  • 1
    The Fibonacci sequence grows very quickly (exponentially), which causes Python to resort to arbitrary precision types. You will need modulo math rules to keep the numbers within 32/64-bit integer range. – meowgoesthedog Jan 02 '19 at 14:47
  • There is a way... Check my answer below. – GeeTransit Jan 02 '19 at 15:05

5 Answers5

2

Look at this table: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html notice that fib(60) last digit is 0 and fib(61) last digit is 1, that is same as fib(0) and fib(1), thus starting at 60 last digits starts to repeat, so you can calculate last digit for fib(n%60) rather than fib(n). For example last digit is same for fib(115) and fib(55) and equal to 5.

Daweo
  • 31,313
  • 3
  • 12
  • 25
1

The series of final digits of Fibonacci numbers repeats with a cycle of 60. Therefore, you can optimize the calculation of the sum of n terms to F((n+2) % 60) - 1. Also, to stay in the integer range, you can keep only the last digit of each term:

def last_digit(n):
    a, b = 0, 1
    for i in range((n + 2) % 60):
        a, b = b, (a + b) % 10
    return 9 if a == 0 else a - 1

print([last_digit(n) for n in range(1, 11)])

Output:

[1, 2, 4, 7, 2, 0, 3, 4, 8, 3]
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
0

Here's code optimized specifically for the last digit:

def fib(n):
    a, b = 0, 1
    r = 1
    if n < 1:
        return 0
    for i in range(n - 1):
        a, b = b, (a + b)%10
        r += b
        r %= 10
    return r

It works by getting only the last digit of the next term and adding that to the result. It then gets the last digit of the result and sets it to itself. It repeats until it gets to the term number and returns a one-digit number :D

Fun Fact: Try the above function on 99. Returns 0. What about 999? 0. 9999? 0. Continue this :D

GeeTransit
  • 1,458
  • 9
  • 22
0

Try to use the Pisano Period property. If you want to compute the last digit, Pisano Period of 10 will be 60. Knowing this, you can have a function similar to:

def fibonacci_sum(n):

    pisano = 60

    if n < 2: return n

    n %= pisano

    fib_arr = [1,1]
    for _ in range(n):
        fib_arr.append((fib_arr[-1] + fib_arr[-2]) % 10)

    return (fib_arr[-1] - 1) % 10

For more information refer to saveriogzz Github CS_Curriculum repo.

Cheers!

0

Here is a simple C++ program

//outputs last digit of ( sum of fib number till n)
#include<iostream>
using namespace std;

int64_t fib_sum_digit(int64_t n)
{
    int fl[60] ={0};
    fl[0] = 0;
    fl[1] = 1;
   // int64_t sum60 = 1;

    for(int i = 2 ; i<60 ; i++)
    {
        fl[i] = (fl[i-1] +fl[i-2])%10 ; 
        //sum60 += fl[i]; 
    }


    int64_t sum = 0;
    // sum += (sum60*(n/60));               ///sum60%10 always  = 0 ;

    for(int i = 1; i<=(n%60); i++ )
    {
        sum += (fl[i]);
        //cout<<i<<","<<sum<<"->";         ///debug
    }

return sum%10;
}

int main()
{
    int64_t n;
    cin>>n;

    int64_t ans = fib_sum_digit(n);
    cout<<ans;

    return 0;
}
Anuraag Barde
  • 399
  • 3
  • 9