-
-
Notifications
You must be signed in to change notification settings - Fork 46.9k
gcd_of_n_numbers #8057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gcd_of_n_numbers #8057
Changes from 18 commits
83aa457
1dd1284
89b8336
3747c46
8996186
bc3ea36
c774f82
0200bd6
e684640
da603f6
95e67aa
27f48bd
e02a30c
2f660fc
4099e95
ec207a8
8406035
99af232
d5681d8
db4f11b
8b321ba
b7473dd
a230d7e
d351516
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
""" | ||
Gcd of N Numbers | ||
Reference: https://en.wikipedia.org/wiki/Greatest_common_divisor | ||
""" | ||
|
||
from collections import Counter | ||
from functools import reduce | ||
|
||
|
||
def get_factors( | ||
number: int, factors: Counter | None = None, factor: int = 2 | ||
) -> Counter: | ||
""" | ||
this is a recursive function for get all factors of number | ||
>>> get_factors(45) | ||
Counter({3: 2, 5: 1}) | ||
>>> get_factors(2520) | ||
Counter({2: 3, 3: 2, 5: 1, 7: 1}) | ||
>>> get_factors(23) | ||
Counter({23: 1}) | ||
>>> get_factors(0) | ||
Traceback (most recent call last): | ||
... | ||
TypeError: number must be integer and greater than zero | ||
>>> get_factors(-1) | ||
Traceback (most recent call last): | ||
... | ||
TypeError: number must be integer and greater than zero | ||
>>> get_factors(1.5) | ||
Traceback (most recent call last): | ||
... | ||
TypeError: number must be integer and greater than zero | ||
|
||
factor can be all numbers from 2 to number that we check if number % factor == 0 | ||
if it is equal to zero, we check again with number // factor | ||
else we increase factor by one | ||
""" | ||
|
||
match number: | ||
dhruvmanila marked this conversation as resolved.
Show resolved
Hide resolved
dhruvmanila marked this conversation as resolved.
Show resolved
Hide resolved
dhruvmanila marked this conversation as resolved.
Show resolved
Hide resolved
|
||
case int(number) if number == 1: | ||
return Counter({1: 1}) | ||
case int(num) if number > 0: | ||
number = num | ||
case _: | ||
raise TypeError("number must be integer and greater than zero") | ||
|
||
factors = factors or Counter() | ||
|
||
if number == factor: # break condition | ||
# all numbers are factors of itself | ||
factors[factor] += 1 | ||
return factors | ||
|
||
if number % factor > 0: | ||
# if it is greater than zero | ||
# so it is not a factor of number and we check next number | ||
return get_factors(number, factors, factor + 1) | ||
|
||
factors[factor] += 1 | ||
# else we update factors (that is Counter(dict-like) type) and check again | ||
return get_factors(number // factor, factors, factor) | ||
|
||
|
||
def get_greatest_common_divisor(*numbers: int) -> int: | ||
""" | ||
get gcd of n numbers: | ||
>>> get_greatest_common_divisor(18, 45) | ||
9 | ||
>>> get_greatest_common_divisor(23, 37) | ||
1 | ||
>>> get_greatest_common_divisor(2520, 8350) | ||
10 | ||
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||
>>> get_greatest_common_divisor(-10, 20) | ||
Traceback (most recent call last): | ||
... | ||
Exception: numbers must be integer and greater than zero | ||
>>> get_greatest_common_divisor(1.5, 2) | ||
Traceback (most recent call last): | ||
... | ||
Exception: numbers must be integer and greater than zero | ||
>>> get_greatest_common_divisor(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) | ||
1 | ||
>>> get_greatest_common_divisor("1", 2, 3, 4, 5, 6, 7, 8, 9, 10) | ||
Traceback (most recent call last): | ||
... | ||
Exception: numbers must be integer and greater than zero | ||
""" | ||
|
||
# we just need factors, not numbers itself | ||
try: | ||
same_factors, *factors = map(get_factors, numbers) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md#coding-style
https://docs.python.org/3/whatsnew/3.0.html#views-and-iterators-instead-of-lists |
||
except TypeError as e: | ||
raise Exception("numbers must be integer and greater than zero") from e | ||
|
||
for factor in factors: | ||
same_factors &= factor | ||
# get common factor between all | ||
# `&` return common elements with smaller value (for Counter type) | ||
|
||
# now, same_factors is something like {2: 2, 3: 4} that means 2 * 2 * 3 * 3 * 3 * 3 | ||
# power each factor and multiply | ||
# for {2: 2, 3: 4}, it is [4, 81] and then 324 | ||
return reduce(lambda x, y: x * y, (factor ** power for factor, power in same_factors.items()), 1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: Please provide descriptive name for the parameter: |
||
|
||
|
||
if __name__ == "__main__": | ||
print(get_greatest_common_divisor(18, 45)) # 9 |
Uh oh!
There was an error while loading. Please reload this page.