|
1 | 1 | """
|
2 | 2 | Gcd of N Numbers
|
3 | 3 | Reference: https://en.wikipedia.org/wiki/Greatest_common_divisor
|
| 4 | +Reference for tail recursion: https://www.geeksforgeeks.org/tail-recursion/ |
4 | 5 | """
|
5 | 6 |
|
6 | 7 | from collections import Counter
|
@@ -104,6 +105,51 @@ def get_greatest_common_divisor(*numbers: int) -> int:
|
104 | 105 | mult *= m
|
105 | 106 | return mult
|
106 | 107 |
|
| 108 | +def gcd_tail_recursive(a: int, b: int) -> int: |
| 109 | + """ |
| 110 | + Calculate the Greatest Common Divisor (GCD) using a tail-recursive approach. |
| 111 | +
|
| 112 | + This function uses the tail-recursive form of the Euclidean algorithm to calculate |
| 113 | + the GCD of two integers `a` and `b`. The GCD is the largest integer that divides both |
| 114 | + `a` and `b` without leaving a remainder. |
| 115 | +
|
| 116 | + Tail recursion is a form of recursion where the recursive call is the last operation |
| 117 | + in the function. In languages that support tail call optimization, this allows the |
| 118 | + function to be optimized by reusing the current function's stack frame for the |
| 119 | + next call. Python, however, does not support tail call optimization, but using this |
| 120 | + style can still help structure the recursion for better clarity. |
| 121 | +
|
| 122 | + Args: |
| 123 | + a (int): The first integer. |
| 124 | + b (int): The second integer. |
| 125 | +
|
| 126 | + Returns: |
| 127 | + int: The greatest common divisor of `a` and `b`. |
| 128 | +
|
| 129 | + Raises: |
| 130 | + ValueError: If both `a` and `b` are zero, as the GCD is not defined for this case. |
| 131 | +
|
| 132 | + Example: |
| 133 | + >>> gcd_tail_recursive(24, 40) |
| 134 | + 8 |
| 135 | + >>> gcd_tail_recursive(11, 37) |
| 136 | + 1 |
| 137 | + >>> gcd_tail_recursive(0, 5) |
| 138 | + 5 |
| 139 | + >>> gcd_tail_recursive(5, 0) |
| 140 | + 5 |
| 141 | + >>> gcd_tail_recursive(0, 0) |
| 142 | + ValueError: GCD is not defined for both a and b being zero. |
| 143 | +
|
| 144 | + Notes: |
| 145 | + - gcd(a, 0) = abs(a) |
| 146 | + - gcd(0, b) = abs(b) |
| 147 | + - gcd(0, 0) is undefined. |
| 148 | + """ |
| 149 | + if b == 0: |
| 150 | + return abs(a) |
| 151 | + return gcd_tail_recursive(b, a % b) |
107 | 152 |
|
108 | 153 | if __name__ == "__main__":
|
109 | 154 | print(get_greatest_common_divisor(18, 45)) # 9
|
| 155 | + print(gcd_tail_recursive(23, 37)) # 1 |
0 commit comments