Also these problems are presented in the the edX MOOC Algs200x Algorithmic Design and Techniques by the UC San Diego, week 2, so I suggest you to give them a try and then comparing your solutions with my python scripts.

**Last Digit of the Sum of Fibonacci Numbers**

Given an integer π, find the last digit of the sum πΉ0 + πΉ1 + · · · + πΉπ.

Considering that n could be as big as 10^14, the naive solution of summing up all the Fibonacci numbers as long as we calculate them is leading too slowly to the result.

We'd better take notice of the hint about experimenting a bit with small test cases looking if we can extrapolate anything interesting. Actually, after a while I find out that the sum of the first n Fibonacci number is just one shorter than the sum of Fibonacci of n + 2.

**Sum of Fib(1) + Fib(2) + ... + Fib(n) = Fib(n+2) - 1**

We know that Fib(3) = Fib(2) + Fib(1), we can rewrite it as

Fib(1) = Fib(3) - Fib(2)Let's do the same for all the subsequent Fibonacci numbers up to n.

Fib(2) = Fib(4) - Fib(3) Fib(3) = Fib(5) - Fib(4) ... Fib(n) = Fib(n+2) - Fib(n+1)If we add up all the elements on the left side we get that the required sum is

Fib(3) - Fib(2) + Fib(4) - Fib(3) + Fib(5) - Fib(4) + ... + Fib(n+2) - Fib(n+1)Considering that Fib(2) is 1, it simplifies to

Fib(n+2) - 1

Putting all together, this is my solution:

PISANO = 60 # 1 def solution(number): if number < 2: return number number %= PISANO results = [1, 1] for _ in range(number): # 2 results.append((results[-1] + results[-2]) % 10) # 3 return (results[-1] - 1) % 10 # 41. Instead of giving the result for the requested number, I check the modulo 60, being that the Pisano period for 10.

2. I have initialized the list named 'results' with the values of Fib(1) and Fib(2), now I loop n times, since I am looking for Fib(n+2).

3. I'm not interested in the actual Fibonacci number, just it's last digit, so here I apply modulo 10 to the brand new calculated one. In this way I avoid scaling to big numbers.

4. I apply the modulo operator once again to get rid of the unfortunate case of possibly negative results.

Naive, Pisano script, and test case for both, are on GitHub.

**Last Digit of the Partial Sum of Fibonacci Numbers**

Given two non-negative integers π and π, where π ≤ π, find the last digit of the sum πΉπ + πΉπ+1 + ... + πΉπ.

The trick used in the previous problem won't work here, and I couldn't think of any similar clever approach. So I resorted to make full use of Pisano, hoping that it was enough.

PISANO = 60 def solution(left, right): assert not left > right # 1 fib_mods = [0, 1] # 2 for _ in range(PISANO - 2): fib_mods.append((fib_mods[-1] + fib_mods[-2]) % 10) left %= PISANO # 3 right %= PISANO if right < left: right += PISANO result = 0 for i in range(left, right + 1): result += fib_mods[i % PISANO] # 4 return result % 10 # 51. Not strictly required by the problem, where we can assume the input data is clean.

2. I fill this list with all the Fibonacci number modulo 10 in the range of the Pisano period.

3. I don't need to loop on all the actual requested numbers, I can safely stay in the limit of the Pisano period. With one major caveat, the right limit should not become smaller that left.

4. Loop on the interval, ensuring that I stay in the Pisano limits.

5. Return the last digit of the sum, as required.

Also for this problem I have pushed naive, Pisano script, and test case for both, on GitHub. See the github folder for all the stuff about week 2 exercises.

Actually, after a while I find out that the sum of the first n Fibonacci number is just one shorter than the sum of Fibonacci of n + 2.

ReplyDeleteI didn't understand this line?

Where did you implemented this line?

Thank you for asking. I answered to the first point in the post, adding a section (in blue) that I hope makes it more clear.

DeleteFor the second point I added a note (now marked as '2') in the code. The idea is that I run the for-loop until I get the modulo of Fibonacci(n+2), so that I just have to decrease it by one to get the expected result.