diff --git a/maths/carmichael_number.py b/maths/carmichael_number.py index 81712520f..08b5c70e8 100644 --- a/maths/carmichael_number.py +++ b/maths/carmichael_number.py @@ -10,10 +10,21 @@ satisfies the following modular arithmetic condition: Examples of Carmichael Numbers: 561, 1105, ... https://en.wikipedia.org/wiki/Carmichael_number """ + from maths.greatest_common_divisor import greatest_common_divisor def power(x: int, y: int, mod: int) -> int: + """ + + Examples: + >>> power(2, 15, 3) + 2 + + >>> power(5, 1, 30) + 5 + """ + if y == 0: return 1 temp = power(x, y // 2, mod) % mod @@ -24,15 +35,47 @@ def power(x: int, y: int, mod: int) -> int: def is_carmichael_number(n: int) -> bool: - b = 2 - while b < n: - if greatest_common_divisor(b, n) == 1 and power(b, n - 1, n) != 1: - return False - b += 1 - return True + """ + + Examples: + >>> is_carmichael_number(562) + False + + >>> is_carmichael_number(561) + True + + >>> is_carmichael_number(5.1) + Traceback (most recent call last): + ... + ValueError: Number 5.1 must instead be a positive integer + + >>> is_carmichael_number(-7) + Traceback (most recent call last): + ... + ValueError: Number -7 must instead be a positive integer + + >>> is_carmichael_number(0) + Traceback (most recent call last): + ... + ValueError: Number 0 must instead be a positive integer + """ + + if n <= 0 or not isinstance(n, int): + msg = f"Number {n} must instead be a positive integer" + raise ValueError(msg) + + return all( + power(b, n - 1, n) == 1 + for b in range(2, n) + if greatest_common_divisor(b, n) == 1 + ) if __name__ == "__main__": + import doctest + + doctest.testmod() + number = int(input("Enter number: ").strip()) if is_carmichael_number(number): print(f"{number} is a Carmichael Number.")