summaryrefslogtreecommitdiff
path: root/AlgoDesignAndTechniqueEdxPython/sources/fibagain.py
blob: 86b51524c57fd59f33161c3b27d1d8f811e33d31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Uses python3
import sys


# def getFib(n):
#     if (n <= 1):
#         return n
#     fibLst = [None] * (n + 1)
#     fibLst[0] = 0
#     fibLst[1] = 1
#     for j in range(2, n + 1):
#         fibLst[j] = fibLst[j - 1] + fibLst[j - 2]
#     return fibLst[n]
# 
# 
# def getFibOptimized(n):
#     if (n <= 1):
#         return n
#     firstFib = 0
#     secondFib = 1
#     tempHolder = 1
#     for _ in range(2, n + 1):
#         tempHolder = firstFib + secondFib
#         firstFib = secondFib
#         secondFib = tempHolder
#     return secondFib


def getPisanoPeriod(m):
    period = 2
    remainder1 = 1
    remainder2 = 1
    
    for _ in range(3, 6 * m + 1):
        period = period + 1
        if (remainder2 == 1) & (remainder1 + remainder2 == m):
            break
        else:
            tempHolder = remainder1 + remainder2
            remainder1 = remainder2
            if tempHolder >= m:
                remainder2 = tempHolder - m
            else:
                remainder2 = tempHolder
                
    return period


def getFibNModM(n, m):
    # https://medium.com/competitive/huge-fibonacci-number-modulo-m-6b4926a5c836
    # the above link helped me in improving my code
    p = getPisanoPeriod(m)
    r = n % p
    if r == 0:
        return 0
    firstN = 0
    secondN = 1
    tempHolder = 1
    for _ in range(2, r + 1):
        tempHolder = (firstN + secondN) % m;
        firstN = secondN
        secondN = tempHolder
#     return getFibOptimized(n % p) % m
    return secondN


if __name__ == '__main__':
    entryNumbers = sys.stdin.read()
    tokens = entryNumbers.split()
    n = int(tokens[0])
    m = int(tokens[1])
    print(getFibNModM(n, m))