-
-
Notifications
You must be signed in to change notification settings - Fork 50.5k
Expand file tree
/
Copy pathbasic_maths.py
More file actions
164 lines (148 loc) · 4 KB
/
basic_maths.py
File metadata and controls
164 lines (148 loc) · 4 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
"""Implementation of Basic Math in Python."""
import math
def gcd(a: int, b: int) -> int:
"""Calculate the Greatest Common Divisor (GCD) using Euclid's Algorithm.
>>> gcd(54, 24)
6
>>> gcd(10, 0)
10
>>> gcd(0, 10)
10
>>> gcd(0, 0)
Traceback (most recent call last):
...
ValueError: At least one number must be non-zero
>>> gcd(-54, 24)
6
"""
if a == 0 and b == 0:
raise ValueError("At least one number must be non-zero")
a, b = abs(a), abs(b)
while b:
a, b = b, a % b
return a
def lcm(a: int, b: int) -> int:
"""Calculate the Least Common Multiple (LCM) using GCD.
>>> lcm(12, 15)
60
>>> lcm(0, 10)
0
>>> lcm(-12, 15)
60
"""
if a == 0 or b == 0:
return 0
return abs(a * b) // gcd(a, b)
def prime_factors(n: int) -> list:
"""
Uses a standard method of dividing by 2, then odd divisors up to sqrt(n).
Time Complexity: O(sqrt(n))
Space Complexity: O(log n) on average
"""
"""Find Prime Factors.
>>> prime_factors(100)
[2, 2, 5, 5]
>>> prime_factors(0)
Traceback (most recent call last):
...
ValueError: Only positive integers have prime factors
>>> prime_factors(-10)
Traceback (most recent call last):
...
ValueError: Only positive integers have prime factors
"""
if n <= 0:
raise ValueError("Only positive integers have prime factors")
pf = []
while n % 2 == 0:
pf.append(2)
n = int(n / 2)
for i in range(3, int(math.sqrt(n)) + 1, 2):
while n % i == 0:
pf.append(i)
n = int(n / i)
if n > 2:
pf.append(n)
return pf
def number_of_divisors(n: int) -> int:
"""Calculate Number of Divisors of an Integer.
>>> number_of_divisors(100)
9
>>> number_of_divisors(0)
Traceback (most recent call last):
...
ValueError: Only positive numbers are accepted
>>> number_of_divisors(-10)
Traceback (most recent call last):
...
ValueError: Only positive numbers are accepted
"""
if n <= 0:
raise ValueError("Only positive numbers are accepted")
div = 1
temp = 1
while n % 2 == 0:
temp += 1
n = int(n / 2)
div *= temp
for i in range(3, int(math.sqrt(n)) + 1, 2):
temp = 1
while n % i == 0:
temp += 1
n = int(n / i)
div *= temp
if n > 1:
div *= 2
return div
def sum_of_divisors(n: int) -> int:
"""Calculate Sum of Divisors.
>>> sum_of_divisors(100)
217
>>> sum_of_divisors(0)
Traceback (most recent call last):
...
ValueError: Only positive numbers are accepted
>>> sum_of_divisors(-10)
Traceback (most recent call last):
...
ValueError: Only positive numbers are accepted
"""
if n <= 0:
raise ValueError("Only positive numbers are accepted")
s = 1
temp = 1
while n % 2 == 0:
temp += 1
n = int(n / 2)
if temp > 1:
s *= (2**temp - 1) / (2 - 1)
for i in range(3, int(math.sqrt(n)) + 1, 2):
temp = 1
while n % i == 0:
temp += 1
n = int(n / i)
if temp > 1:
s *= (i**temp - 1) / (i - 1)
return int(s)
def euler_phi(n: int) -> int:
"""Calculate Euler's Phi Function.
>>> euler_phi(100)
40
>>> euler_phi(0)
Traceback (most recent call last):
...
ValueError: Only positive numbers are accepted
>>> euler_phi(-10)
Traceback (most recent call last):
...
ValueError: Only positive numbers are accepted
"""
if n <= 0:
raise ValueError("Only positive numbers are accepted")
s = n
for x in set(prime_factors(n)):
s *= (x - 1) / x
return int(s)
if __name__ == "__main__":
import doctest
doctest.testmod()