@@ -107,3 +107,48 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
107107 testmod (name = "diophantine_all_soln" , verbose = True )
108108 testmod (name = "extended_gcd" , verbose = True )
109109 testmod (name = "greatest_common_divisor" , verbose = True )
110+
111+ from __future__ import annotations
112+
113+ def all_diophantine_solutions (a : int , b : int , c : int , n : int = 2 ) -> list [tuple [int , int ]]:
114+ """
115+ Return up to `n` integer solutions (x, y) to the linear Diophantine equation
116+ a*x + b*y = c using the extended Euclidean algorithm.
117+
118+ Raises:
119+ ValueError: If no integer solutions exist.
120+
121+ Time complexity: O(log(max(|a|, |b|))) to compute one base solution via extended_gcd,
122+ plus O(n) to enumerate `n` solutions.
123+ Space complexity: O(1) beyond the returned list.
124+
125+ Examples
126+ --------
127+ >>> all_diophantine_solutions(10, 6, 14, n=2)
128+ [(-7, 14), (-4, 9)]
129+ >>> all_diophantine_solutions(10, 6, 14, n=4)
130+ [(-7, 14), (-4, 9), (-1, 4), (2, -1)]
131+ >>> all_diophantine_solutions(3, 6, 10, n=1)
132+ Traceback (most recent call last):
133+ ...
134+ ValueError: No integer solutions exist for a=3, b=6, c=10
135+ """
136+ if a == 0 and b == 0 :
137+ if c == 0 :
138+ return [(0 , 0 )][: min (1 , n )]
139+ raise ValueError ("No integer solutions exist for a=0, b=0, c!=0" )
140+
141+ g , xg , yg = extended_gcd (abs (a ), abs (b ))
142+ if c % g != 0 :
143+ raise ValueError (f"No integer solutions exist for a={ a } , b={ b } , c={ c } " )
144+
145+ # Scale a particular solution to ax + by = c
146+ x0 , y0 = xg * (c // g ), yg * (c // g )
147+ if a < 0 :
148+ x0 = - x0
149+ if b < 0 :
150+ y0 = - y0
151+
152+ # General solution: x = x0 + t*(b/g), y = y0 - t*(a/g)
153+ dx , dy = b // g , a // g
154+ return [(x0 + t * dx , y0 - t * dy ) for t in range (n )]
0 commit comments