diff --git a/maths/number_of_digits.py b/maths/number_of_digits.py index 30e82f60f..4bafa613c 100644 --- a/maths/number_of_digits.py +++ b/maths/number_of_digits.py @@ -1,3 +1,7 @@ +import math +from timeit import timeit + + def num_digits(n: int) -> int: """ Find the number of digits in a number. @@ -14,5 +18,82 @@ def num_digits(n: int) -> int: return digits +def num_digits_fast(n: int) -> int: + """ + Find the number of digits in a number. + abs() is used as logarithm for negative numbers is not defined. + + >>> num_digits_fast(12345) + 5 + >>> num_digits_fast(123) + 3 + """ + return (math.floor(math.log(abs(n), 10) + 1)) + + +def num_digits_faster(n: int) -> int: + """ + Find the number of digits in a number. + abs() is used for negative numbers + + >>> num_digits_faster(12345) + 5 + >>> num_digits_faster(123) + 3 + """ + return (len(str(abs(n)))) + + +def benchmark() -> None: + """ + Benchmark code for comparing 3 functions, + with 3 different length int values. + """ + print('\nFor small_num = ', small_num, ':') + print("> num_digits()", + '\t\tans =', num_digits(small_num), + '\ttime =', timeit("z.num_digits(z.small_num)", + setup="import __main__ as z"), "seconds") + print("> num_digits_fast()", + '\tans =', num_digits_fast(small_num), + '\ttime =', timeit("z.num_digits_fast(z.small_num)", + setup="import __main__ as z"), "seconds") + print("> num_digits_faster()", + '\tans =', num_digits_faster(small_num), + '\ttime =', timeit("z.num_digits_faster(z.small_num)", + setup="import __main__ as z"), "seconds") + + print('\nFor medium_num = ', medium_num, ':') + print("> num_digits()", + '\t\tans =', num_digits(medium_num), + '\ttime =', timeit("z.num_digits(z.medium_num)", + setup="import __main__ as z"), "seconds") + print("> num_digits_fast()", + '\tans =', num_digits_fast(medium_num), + '\ttime =', timeit("z.num_digits_fast(z.medium_num)", + setup="import __main__ as z"), "seconds") + print("> num_digits_faster()", + '\tans =', num_digits_faster(medium_num), + '\ttime =', timeit("z.num_digits_faster(z.medium_num)", + setup="import __main__ as z"), "seconds") + + print('\nFor large_num = ', large_num, ':') + print("> num_digits()", + '\t\tans =', num_digits(large_num), + '\ttime =', timeit("z.num_digits(z.large_num)", + setup="import __main__ as z"), "seconds") + print("> num_digits_fast()", + '\tans =', num_digits_fast(large_num), + '\ttime =', timeit("z.num_digits_fast(z.large_num)", + setup="import __main__ as z"), "seconds") + print("> num_digits_faster()", + '\tans =', num_digits_faster(large_num), + '\ttime =', timeit("z.num_digits_faster(z.large_num)", + setup="import __main__ as z"), "seconds") + + if __name__ == "__main__": - print(num_digits(12345)) # ===> 5 + small_num = 262144 + medium_num = 1125899906842624 + large_num = 1267650600228229401496703205376 + benchmark()