diff --git a/maths/least_common_multiple.py b/maths/least_common_multiple.py index 863744e18..0d087643e 100644 --- a/maths/least_common_multiple.py +++ b/maths/least_common_multiple.py @@ -1,15 +1,17 @@ import unittest +from timeit import timeit -def find_lcm(first_num: int, second_num: int) -> int: - """Find the least common multiple of two numbers. +def least_common_multiple_slow(first_num: int, second_num: int) -> int: + """ + Find the least common multiple of two numbers. - Learn more: https://en.wikipedia.org/wiki/Least_common_multiple + Learn more: https://en.wikipedia.org/wiki/Least_common_multiple - >>> find_lcm(5,2) - 10 - >>> find_lcm(12,76) - 228 + >>> least_common_multiple_slow(5, 2) + 10 + >>> least_common_multiple_slow(12, 76) + 228 """ max_num = first_num if first_num >= second_num else second_num common_mult = max_num @@ -18,6 +20,52 @@ def find_lcm(first_num: int, second_num: int) -> int: return common_mult +def greatest_common_divisor(a: int, b: int) -> int: + """ + Calculate Greatest Common Divisor (GCD). + see greatest_common_divisor.py + >>> greatest_common_divisor(24, 40) + 8 + >>> greatest_common_divisor(1, 1) + 1 + >>> greatest_common_divisor(1, 800) + 1 + >>> greatest_common_divisor(11, 37) + 1 + >>> greatest_common_divisor(3, 5) + 1 + >>> greatest_common_divisor(16, 4) + 4 + """ + return b if a == 0 else greatest_common_divisor(b % a, a) + + +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), + ) + + class TestLeastCommonMultiple(unittest.TestCase): test_inputs = [ @@ -35,10 +83,13 @@ class TestLeastCommonMultiple(unittest.TestCase): def test_lcm_function(self): for i, (first_num, second_num) in enumerate(self.test_inputs): - actual_result = find_lcm(first_num, second_num) + slow_result = least_common_multiple_slow(first_num, second_num) + fast_result = least_common_multiple_fast(first_num, second_num) with self.subTest(i=i): - self.assertEqual(actual_result, self.expected_results[i]) + self.assertEqual(slow_result, self.expected_results[i]) + self.assertEqual(fast_result, self.expected_results[i]) if __name__ == "__main__": + benchmark() unittest.main()