2019-10-18 05:35:29 +00:00
|
|
|
import unittest
|
2020-08-05 10:39:15 +00:00
|
|
|
from timeit import timeit
|
2019-10-18 05:35:29 +00:00
|
|
|
|
2023-10-09 12:19:12 +00:00
|
|
|
from maths.greatest_common_divisor import greatest_common_divisor
|
|
|
|
|
2019-10-18 05:35:29 +00:00
|
|
|
|
2020-08-05 10:39:15 +00:00
|
|
|
def least_common_multiple_slow(first_num: int, second_num: int) -> int:
|
|
|
|
"""
|
|
|
|
Find the least common multiple of two numbers.
|
2019-10-18 05:35:29 +00:00
|
|
|
|
2020-08-05 10:39:15 +00:00
|
|
|
Learn more: https://en.wikipedia.org/wiki/Least_common_multiple
|
2019-10-18 05:35:29 +00:00
|
|
|
|
2020-08-05 10:39:15 +00:00
|
|
|
>>> least_common_multiple_slow(5, 2)
|
|
|
|
10
|
|
|
|
>>> least_common_multiple_slow(12, 76)
|
|
|
|
228
|
2019-10-18 05:35:29 +00:00
|
|
|
"""
|
|
|
|
max_num = first_num if first_num >= second_num else second_num
|
|
|
|
common_mult = max_num
|
|
|
|
while (common_mult % first_num > 0) or (common_mult % second_num > 0):
|
|
|
|
common_mult += max_num
|
|
|
|
return common_mult
|
|
|
|
|
|
|
|
|
2020-08-05 10:39:15 +00:00
|
|
|
def least_common_multiple_fast(first_num: int, second_num: int) -> int:
|
|
|
|
"""
|
|
|
|
Find the least common multiple of two numbers.
|
|
|
|
https://en.wikipedia.org/wiki/Least_common_multiple#Using_the_greatest_common_divisor
|
|
|
|
>>> least_common_multiple_fast(5,2)
|
|
|
|
10
|
|
|
|
>>> least_common_multiple_fast(12,76)
|
|
|
|
228
|
|
|
|
"""
|
|
|
|
return first_num // greatest_common_divisor(first_num, second_num) * second_num
|
|
|
|
|
|
|
|
|
|
|
|
def benchmark():
|
|
|
|
setup = (
|
|
|
|
"from __main__ import least_common_multiple_slow, least_common_multiple_fast"
|
|
|
|
)
|
|
|
|
print(
|
|
|
|
"least_common_multiple_slow():",
|
|
|
|
timeit("least_common_multiple_slow(1000, 999)", setup=setup),
|
|
|
|
)
|
|
|
|
print(
|
|
|
|
"least_common_multiple_fast():",
|
|
|
|
timeit("least_common_multiple_fast(1000, 999)", setup=setup),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-10-18 05:35:29 +00:00
|
|
|
class TestLeastCommonMultiple(unittest.TestCase):
|
2023-06-22 11:49:09 +00:00
|
|
|
test_inputs = (
|
2019-10-18 05:35:29 +00:00
|
|
|
(10, 20),
|
|
|
|
(13, 15),
|
|
|
|
(4, 31),
|
|
|
|
(10, 42),
|
|
|
|
(43, 34),
|
|
|
|
(5, 12),
|
|
|
|
(12, 25),
|
|
|
|
(10, 25),
|
|
|
|
(6, 9),
|
2023-06-22 11:49:09 +00:00
|
|
|
)
|
|
|
|
expected_results = (20, 195, 124, 210, 1462, 60, 300, 50, 18)
|
2019-10-18 05:35:29 +00:00
|
|
|
|
|
|
|
def test_lcm_function(self):
|
|
|
|
for i, (first_num, second_num) in enumerate(self.test_inputs):
|
2020-08-05 10:39:15 +00:00
|
|
|
slow_result = least_common_multiple_slow(first_num, second_num)
|
|
|
|
fast_result = least_common_multiple_fast(first_num, second_num)
|
2019-10-18 05:35:29 +00:00
|
|
|
with self.subTest(i=i):
|
2023-10-11 18:30:02 +00:00
|
|
|
assert slow_result == self.expected_results[i]
|
|
|
|
assert fast_result == self.expected_results[i]
|
2019-10-18 05:35:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2020-08-05 10:39:15 +00:00
|
|
|
benchmark()
|
2019-10-18 05:35:29 +00:00
|
|
|
unittest.main()
|