Skip to content

Commit 6fb38f0

Browse files
balakhaniyanpre-commit-ci[bot]
authored andcommitted
gcd_of_n_numbers (TheAlgorithms#8057)
* add maths/Gcd of N Numbers * add maths/Gcd of N Numbers * add maths/Gcd of N Numbers * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add maths/Gcd of N Numbers * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add maths/Gcd of N Numbers * add maths/Gcd of N Numbers * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add maths/Gcd of N Numbers * add maths/Gcd of N Numbers * more pythonic * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * more pythonic * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * merged * merged * more readable * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 7c234b2 commit 6fb38f0

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

maths/gcd_of_n_numbers.py

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""
2+
Gcd of N Numbers
3+
Reference: https://en.wikipedia.org/wiki/Greatest_common_divisor
4+
"""
5+
6+
from collections import Counter
7+
8+
9+
def get_factors(
10+
number: int, factors: Counter | None = None, factor: int = 2
11+
) -> Counter:
12+
"""
13+
this is a recursive function for get all factors of number
14+
>>> get_factors(45)
15+
Counter({3: 2, 5: 1})
16+
>>> get_factors(2520)
17+
Counter({2: 3, 3: 2, 5: 1, 7: 1})
18+
>>> get_factors(23)
19+
Counter({23: 1})
20+
>>> get_factors(0)
21+
Traceback (most recent call last):
22+
...
23+
TypeError: number must be integer and greater than zero
24+
>>> get_factors(-1)
25+
Traceback (most recent call last):
26+
...
27+
TypeError: number must be integer and greater than zero
28+
>>> get_factors(1.5)
29+
Traceback (most recent call last):
30+
...
31+
TypeError: number must be integer and greater than zero
32+
33+
factor can be all numbers from 2 to number that we check if number % factor == 0
34+
if it is equal to zero, we check again with number // factor
35+
else we increase factor by one
36+
"""
37+
38+
match number:
39+
case int(number) if number == 1:
40+
return Counter({1: 1})
41+
case int(num) if number > 0:
42+
number = num
43+
case _:
44+
raise TypeError("number must be integer and greater than zero")
45+
46+
factors = factors or Counter()
47+
48+
if number == factor: # break condition
49+
# all numbers are factors of itself
50+
factors[factor] += 1
51+
return factors
52+
53+
if number % factor > 0:
54+
# if it is greater than zero
55+
# so it is not a factor of number and we check next number
56+
return get_factors(number, factors, factor + 1)
57+
58+
factors[factor] += 1
59+
# else we update factors (that is Counter(dict-like) type) and check again
60+
return get_factors(number // factor, factors, factor)
61+
62+
63+
def get_greatest_common_divisor(*numbers: int) -> int:
64+
"""
65+
get gcd of n numbers:
66+
>>> get_greatest_common_divisor(18, 45)
67+
9
68+
>>> get_greatest_common_divisor(23, 37)
69+
1
70+
>>> get_greatest_common_divisor(2520, 8350)
71+
10
72+
>>> get_greatest_common_divisor(-10, 20)
73+
Traceback (most recent call last):
74+
...
75+
Exception: numbers must be integer and greater than zero
76+
>>> get_greatest_common_divisor(1.5, 2)
77+
Traceback (most recent call last):
78+
...
79+
Exception: numbers must be integer and greater than zero
80+
>>> get_greatest_common_divisor(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
81+
1
82+
>>> get_greatest_common_divisor("1", 2, 3, 4, 5, 6, 7, 8, 9, 10)
83+
Traceback (most recent call last):
84+
...
85+
Exception: numbers must be integer and greater than zero
86+
"""
87+
88+
# we just need factors, not numbers itself
89+
try:
90+
same_factors, *factors = map(get_factors, numbers)
91+
except TypeError as e:
92+
raise Exception("numbers must be integer and greater than zero") from e
93+
94+
for factor in factors:
95+
same_factors &= factor
96+
# get common factor between all
97+
# `&` return common elements with smaller value (for Counter type)
98+
99+
# now, same_factors is something like {2: 2, 3: 4} that means 2 * 2 * 3 * 3 * 3 * 3
100+
mult = 1
101+
# power each factor and multiply
102+
# for {2: 2, 3: 4}, it is [4, 81] and then 324
103+
for m in [factor**power for factor, power in same_factors.items()]:
104+
mult *= m
105+
return mult
106+
107+
108+
if __name__ == "__main__":
109+
print(get_greatest_common_divisor(18, 45)) # 9

0 commit comments

Comments
 (0)