I am trying to write code to find one solution to satisfy Diophantine equations $ax + by = c$ given a, b, and c (will use a = 172, b = 20, c = 1000 for example).
Here is the method I am following, and I am stuck on step #2. How can I generalize this algorithm or what would be some tips for writing the proper prior steps into the division algorithm to get the right values?
Use the division algorithm to find the greatest common denominator "d" between a and b: I am doing this using a function. Store values during this in lists so they can be reproduced. I believe I'm successful in this so far. See code snippet #1.
Use the Euclidean Algorithm to then "work backwards" using the formulas during the division algorithm to get coefficients $x_0$ and $y_0$ such that $ax_0 + by_0 = d$ .
Find p such that $c = dp$ .
Then use $x_0 = x*p$ and $y_0 = y*p$ for the solutions of $c = ax + by$ .
Code snippet #1
clist = list()
dlist = list()
ilist = list()
rlist = list()
def gcd(a, b):
assert a >= 0 and b >= 0 and a + b > 0
if a > 0 and b > 0:
if a>b:
dlist.append(int(a/b))
else:
dlist.append(int(b/a))
while a > 0 and b > 0:
if a >= b:
ilist.append(a)
a = a % b
clist.append(a)
if a > 0 and b > 0: #trivial recomparison
if a>b:
dlist.append(int(a/b))
else:
dlist.append(int(b/a))
rlist.append(max(a,b))
print("a executed") #debugging print
else:
ilist.append(b)
b = b % a
clist.append(b)
if a > 0 and b > 0:
if a>b:
dlist.append(int(a/b))
else:
dlist.append(int(b/a))
rlist.append(max(a,b))
print("b executed") #debugging print
print("clist:", clist)
print("dlist:", dlist)
print("ilist:", ilist)
print("rlist:", rlist)
return max(a, b)
print(gcd(172,20))
Output is as follows:
a executed
b executed
a executed
b executed
clist: [12, 8, 4, 0]
dlist: [8, 1, 1, 2]
ilist: [172, 20, 12, 8]
rlist: [20, 12, 8, 4]
4
I understand how to do the following (solving for #2 above) manually, but there are steps like simplifying and factoring that I am having trouble getting into Python. Would really appreciate some recommendations!
Manually, I know I can get one solution by following this path:
- Solve for the remainder: $$ 172/20 = 8 R 12 $$ $$ 20/12 = 1 R 8 $$ $$ 12/8 = 1 R 4 $$ --> 4 is thus the final remainder and the gcd $$ 8/4 = 2 R 0 $$
Restated as three equations, $$ 12 = 172 - 1 * 20 $$ $$ 8 = 20 - 1 * 12 $$ $$ 4 = 12 - 1 * 8 $$
So working backwards and re-factoring: $$ 4 = 12 - 1 * 8 $$ $$ 4 = 12 - 1 * (20 - 1 * 12) $$ $$ 4 = 2 * 12 - 1 * 20 $$ $$ 4 = 2 * (172 - 8 * 20) - 1 * 20 $$ $$ 4 = 2 * 172 + (-17) * 20 $$ Therefore, 2 and -17 are solutions, and I'd like to be able to achieve this in code but I'm a ways away. Part of the problem is I am not sure if there's an easy way to generalize this method.
New on the site, new to computer science, and new to discrete math so I don't mind constructive criticism on all three of these.