Skip to content

Commit af3fe34

Browse files
committed
Initial commit
0 parents  commit af3fe34

File tree

201 files changed

+6757
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

201 files changed

+6757
-0
lines changed

.idea/.gitignore

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/Algorithmic Toolbox.iml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/codeStyles/Project.xml

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/codeStyles/codeStyleConfig.xml

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/externalDependencies.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+88
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# python3
2+
3+
4+
def fibonacci_number_again_naive(n, m):
5+
assert 0 <= n <= 10 ** 18 and 2 <= m <= 10 ** 3
6+
7+
if n <= 1:
8+
return n
9+
10+
previous, current = 0, 1
11+
for _ in range(n - 1):
12+
previous, current = current, (previous + current) % m
13+
14+
return current
15+
16+
17+
def fibonacci_number_again(n, m):
18+
assert 0 <= n <= 10 ** 18 and 2 <= m <= 10 ** 3
19+
20+
type here
21+
22+
23+
if __name__ == '__main__':
24+
input_n, input_m = map(int, input().split())
25+
print(fibonacci_number_again(input_n, input_m))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import unittest
2+
from itertools import product
3+
from fibonacci_number_again import fibonacci_number_again, fibonacci_number_again_naive
4+
5+
6+
class TestFibonacciNumberAgain(unittest.TestCase):
7+
def test_small(self):
8+
for n, m in product(range(2, 15), repeat=2):
9+
self.assertEqual(fibonacci_number_again(n, m), fibonacci_number_again_naive(n, m))
10+
11+
def test_large(self):
12+
for (n, m, r) in [(115, 1000, 885), (2816213588, 239, 151), type here]:
13+
self.assertEqual(fibonacci_number_again(n, m), r)
14+
15+
16+
if __name__ == '__main__':
17+
unittest.main()
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
type: edu
2+
files:
3+
- name: fibonacci_number_again.py
4+
visible: true
5+
placeholders:
6+
- offset: 369
7+
length: 9
8+
placeholder_text: type here
9+
initial_state:
10+
length: 9
11+
offset: 369
12+
initialized_from_dependency: false
13+
selected: false
14+
status: Unchecked
15+
text: |
16+
# python3
17+
18+
19+
def fibonacci_number_again_naive(n, m):
20+
assert 0 <= n <= 10 ** 18 and 2 <= m <= 10 ** 3
21+
22+
if n <= 1:
23+
return n
24+
25+
previous, current = 0, 1
26+
for _ in range(n - 1):
27+
previous, current = current, (previous + current) % m
28+
29+
return current
30+
31+
32+
def fibonacci_number_again(n, m):
33+
assert 0 <= n <= 10 ** 18 and 2 <= m <= 10 ** 3
34+
35+
type here
36+
37+
38+
if __name__ == '__main__':
39+
input_n, input_m = map(int, input().split())
40+
print(fibonacci_number_again(input_n, input_m))
41+
learner_created: false
42+
- name: fibonacci_number_again_unit_tests.py
43+
visible: true
44+
placeholders:
45+
- offset: 456
46+
length: 9
47+
placeholder_text: type here
48+
initial_state:
49+
length: 9
50+
offset: 456
51+
initialized_from_dependency: false
52+
selected: false
53+
status: Unchecked
54+
text: |
55+
import unittest
56+
from itertools import product
57+
from fibonacci_number_again import fibonacci_number_again, fibonacci_number_again_naive
58+
59+
60+
class TestFibonacciNumberAgain(unittest.TestCase):
61+
def test_small(self):
62+
for n, m in product(range(2, 15), repeat=2):
63+
self.assertEqual(fibonacci_number_again(n, m), fibonacci_number_again_naive(n, m))
64+
65+
def test_large(self):
66+
for (n, m, r) in [(115, 1000, 885), (2816213588, 239, 151), type here]:
67+
self.assertEqual(fibonacci_number_again(n, m), r)
68+
69+
70+
if __name__ == '__main__':
71+
unittest.main()
72+
learner_created: false
73+
- name: logo.png
74+
visible: false
75+
learner_created: false
76+
- name: table1.png
77+
visible: false
78+
learner_created: false
79+
- name: table2.png
80+
visible: false
81+
learner_created: false
82+
- name: tests.py
83+
visible: false
84+
text: |
85+
from test_helper import run_common_tests, failed, passed, check_tests_pass
86+
from fibonacci_number_again import fibonacci_number_again
87+
88+
89+
def pisano_period(m):
90+
current, next = 0, 1
91+
period = 0
92+
93+
while True:
94+
current, next = next, (current + next) % m
95+
period += 1
96+
if current == 0 and next == 1:
97+
return period
98+
99+
100+
def fib_mod(n, m):
101+
current, next = 0, 1
102+
for _ in range(n):
103+
current, next = next, (current + next) % m
104+
105+
return current
106+
107+
108+
if __name__ == '__main__':
109+
run_common_tests()
110+
check_tests_pass("fibonacci_number_again_unit_tests.py")
111+
112+
all_tests_passed = True
113+
for (n, m) in [(7, 239), (239, 7), (10 ** 18, 239)]:
114+
if fibonacci_number_again(n, m) != fib_mod(n % pisano_period(m), m):
115+
all_tests_passed = False
116+
failed("Wrong answer for n={}".format(m))
117+
break
118+
119+
if all_tests_passed:
120+
passed()
121+
learner_created: false
122+
feedback_link: https://www.coursera.org/learn/algorithmic-toolbox/programming/b66y2/programming-assignment-2-algorithmic-warm-up/discussions
123+
status: Unchecked
124+
record: -1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Fibonacci Number Again
2+
3+
<center><img src="logo.png" height="200px"></center>
4+
5+
Given two integers $0 \le n \le 10^{18}$ and
6+
$2 \le m \le 10^3$,
7+
compute the $n$-th Fibonacci number modulo $m$.
8+
9+
In this problem, $n$ may be so huge that an algorithm looping for $n$ iterations will be too slow. Therefore we need to avoid such a loop.
10+
To get an idea how to solve this problem without going through all Fibonacci numbers
11+
$F_i$ for $i$ from $0$ to $n$,
12+
take a look at the table below:
13+
14+
<center><img src="table1.png"></center>
15+
16+
Do you see any interesting properties of the last two rows in the table above?
17+
18+
Both these sequences are periodic! For $m=2$, the period is $0 1 1$ and has length $3$, while for $m=3$ the period is $0 1 1 2 0 2 2 1$ and has length $8$.
19+
20+
<center><img src="table2.png"></center>
21+
22+
Therefore, to compute, say, $F_{2015} \bmod{3}$ we just need to find the remainder of $2015$ when divided by $8$. Since $2015=251 \cdot 8 + 7$, we conclude that $F_{2015} \bmod{3} = F_{7} \bmod{3}=1$.
23+
24+
It turns out that for any integer $m \ge 2$,
25+
the sequence $F_n \bmod{m}$ is periodic.
26+
The period always starts with $0 1$ and is
27+
known as *Pisano period*
28+
(Pisano is another name of Fibonacci).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from test_helper import run_common_tests, failed, passed, check_tests_pass
2+
from fibonacci_number_again import fibonacci_number_again
3+
4+
5+
def pisano_period(m):
6+
current, next = 0, 1
7+
period = 0
8+
9+
while True:
10+
current, next = next, (current + next) % m
11+
period += 1
12+
if current == 0 and next == 1:
13+
return period
14+
15+
16+
def fib_mod(n, m):
17+
current, next = 0, 1
18+
for _ in range(n):
19+
current, next = next, (current + next) % m
20+
21+
return current
22+
23+
24+
if __name__ == '__main__':
25+
run_common_tests()
26+
check_tests_pass("fibonacci_number_again_unit_tests.py")
27+
28+
all_tests_passed = True
29+
for (n, m) in [(7, 239), (239, 7), (10 ** 18, 239)]:
30+
if fibonacci_number_again(n, m) != fib_mod(n % pisano_period(m), m):
31+
all_tests_passed = False
32+
failed("Wrong answer for n={}".format(m))
33+
break
34+
35+
if all_tests_passed:
36+
passed()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# python3
2+
3+
4+
def fibonacci_number_naive(n):
5+
assert 0 <= n <= 45
6+
7+
if n <= 1:
8+
return n
9+
10+
return fibonacci_number_naive(n - 1) + fibonacci_number_naive(n - 2)
11+
12+
13+
def fibonacci_number(n):
14+
assert 0 <= n <= 45
15+
16+
type here
17+
18+
19+
if __name__ == '__main__':
20+
input_n = int(input())
21+
print(fibonacci_number(input_n))

0 commit comments

Comments
 (0)