Skip to content

Commit 502cf79

Browse files
committed
feat(blockchain): add all_diophantine_solutions; move above __main__, remove future import
1 parent 14b96e6 commit 502cf79

1 file changed

Lines changed: 29 additions & 16 deletions

File tree

blockchain/diophantine_equation.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,27 +100,29 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
100100
return (d, x, y)
101101

102102

103-
if __name__ == "__main__":
104-
from doctest import testmod
105-
106-
testmod(name="diophantine", verbose=True)
107-
testmod(name="diophantine_all_soln", verbose=True)
108-
testmod(name="extended_gcd", verbose=True)
109-
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]]:
103+
def all_diophantine_solutions(
104+
a: int,
105+
b: int,
106+
c: int,
107+
n: int = 2,
108+
) -> list[tuple[int, int]]:
114109
"""
115110
Return up to `n` integer solutions (x, y) to the linear Diophantine equation
116111
a*x + b*y = c using the extended Euclidean algorithm.
117112
118-
Raises:
119-
ValueError: If no integer solutions exist.
113+
Raises
114+
------
115+
ValueError
116+
If no integer solutions exist.
120117
121-
Time complexity: O(log(max(|a|, |b|))) to compute one base solution via extended_gcd,
118+
Time complexity
119+
---------------
120+
O(log(max(|a|, |b|))) to compute a base solution using extended_gcd;
122121
plus O(n) to enumerate `n` solutions.
123-
Space complexity: O(1) beyond the returned list.
122+
123+
Space complexity
124+
----------------
125+
O(1) beyond the returned list.
124126
125127
Examples
126128
--------
@@ -135,12 +137,14 @@ def all_diophantine_solutions(a: int, b: int, c: int, n: int = 2) -> list[tuple[
135137
"""
136138
if a == 0 and b == 0:
137139
if c == 0:
140+
# Infinite solutions; return one canonical solution.
138141
return [(0, 0)][: min(1, n)]
139142
raise ValueError("No integer solutions exist for a=0, b=0, c!=0")
140143

141144
g, xg, yg = extended_gcd(abs(a), abs(b))
142145
if c % g != 0:
143-
raise ValueError(f"No integer solutions exist for a={a}, b={b}, c={c}")
146+
msg = f"No integer solutions exist for a={a}, b={b}, c={c}"
147+
raise ValueError(msg)
144148

145149
# Scale a particular solution to ax + by = c
146150
x0, y0 = xg * (c // g), yg * (c // g)
@@ -152,3 +156,12 @@ def all_diophantine_solutions(a: int, b: int, c: int, n: int = 2) -> list[tuple[
152156
# General solution: x = x0 + t*(b/g), y = y0 - t*(a/g)
153157
dx, dy = b // g, a // g
154158
return [(x0 + t * dx, y0 - t * dy) for t in range(n)]
159+
160+
161+
if __name__ == "__main__":
162+
from doctest import testmod
163+
164+
testmod(name="diophantine", verbose=True)
165+
testmod(name="diophantine_all_soln", verbose=True)
166+
testmod(name="extended_gcd", verbose=True)
167+
testmod(name="greatest_common_divisor", verbose=True)

0 commit comments

Comments
 (0)