473,385 Members | 2,162 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Euclid's Algorithm in Python?

In Fundamental Algorithms (The Art of Computer Programming), the first
algorithm discussed is Euclid's Algorithm.

The only idea I have of writing this in python is that it must involve
usage of the modulo % sign.

How do I write this in python?

Aug 5 '05 #1
12 14833
Well, this article
http://pythonjournal.cognizor.com/py...rithms-V1.html
was the first hit on google for '"euclid's algorithm" python'.

It contains this function:
def GCD(a,b):
assert a >= b # a must be the larger number
while (b != 0):
remainder = a % b
a, b = b, remainder
return a

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFC8tQQJd01MZaTXX0RAo6iAJ9JUzRbQ4Cvthgp9+pr3M HGiER/tACgl5rQ
bbHUVwSg5xRPhWdRAINbMTQ=
=Ah8K
-----END PGP SIGNATURE-----

Aug 5 '05 #2
Raising an assertion error for a < b is a bit of overkill, since its
not really a case of bad input. So normally you see Euclid done like
this:

def gcd(a,b): # All lowercase for a function is a bit more
conventional.
if a < b:
a, b = b, a # Ensures a >= b by swapping a and b if nessecary
while b != 0: # Note parentheses are unnessecary here in python
a, b = b, a % b
return a

A bit more concise and no less readable (IMO).

If you really want to check for actual bad input, youre better off
testing, for example, than a and b are both greater than 0....

je****@unpythonic.net wrote:
Well, this article
http://pythonjournal.cognizor.com/py...rithms-V1.html
was the first hit on google for '"euclid's algorithm" python'.

It contains this function:
def GCD(a,b):
assert a >= b # a must be the larger number
while (b != 0):
remainder = a % b
a, b = b, remainder
return a

Jeff


Aug 5 '05 #3
Op 2005-08-05, Jordan Rastrick schreef <jr*******@student.usyd.edu.au>:
Raising an assertion error for a < b is a bit of overkill, since its
not really a case of bad input. So normally you see Euclid done like
this:

def gcd(a,b): # All lowercase for a function is a bit more
conventional.
if a < b:
a, b = b, a # Ensures a >= b by swapping a and b if nessecary
while b != 0: # Note parentheses are unnessecary here in python
a, b = b, a % b
return a

A bit more concise and no less readable (IMO).


The if test is unnecessary. Should a be smaller than b, the two values
will be swapped by the while body.

--
Antoon Pardon
Aug 5 '05 #4
On Thu, Aug 04, 2005 at 08:13:11PM -0700, Jordan Rastrick wrote:
Raising an assertion error for a < b is a bit of overkill, since its
not really a case of bad input. So normally you see Euclid done like
this:

[snipped]

My point was not so much that this was the ultimate implementation of GCD, but
that the obvious search would have turned up many enlightening results,
including the topmost one.

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFC85WLJd01MZaTXX0RAsS9AJ0dbdmXeQoM1AxnpXfRa+ X1fAwtWgCgoxmA
C0BvGhd+MIkNefEc+bEnIic=
=iTav
-----END PGP SIGNATURE-----

Aug 5 '05 #5
So, I did the following:
---
a=input("Give me an integer")
b=input("Give me another integer")

def gcd(a,b):

if a < b:
a, b = b, a
while b != 0:
a, b = b, a % b
return a
---
But, in the xterm, it terminates after "Give me another integer."

Is Euclid's Algorithm supposed to be implemented in such a way as to be
used as a tool to find the GCD of two integers, or have I
misinterpreted the intent of the algorithm?

Aug 7 '05 #6
Erik the Red wrote:
So, I did the following:
---
a=input("Give me an integer")
b=input("Give me another integer")

def gcd(a,b):

if a < b:
a, b = b, a
while b != 0:
a, b = b, a % b
return a
---
But, in the xterm, it terminates after "Give me another integer."

Is Euclid's Algorithm supposed to be implemented in such a way as to be
used as a tool to find the GCD of two integers, or have I
misinterpreted the intent of the algorithm?


You do not do anything after both input() calls. You define the function, but
never call it.

Add
print gcd(a, b)
to the end and it will print your result.

Note that the variable names a and b in the function don't have anything to
do with your two input variables.

Reinhold
Aug 7 '05 #7
Good point. I suppose I'd only ever seen it implemented with the if
test, but you're right, the plain while loop should work fine. Silly
me.

def gcd(a,b):
while b != 0:
a, b = b, a%b
return a

Even nicer.

Aug 8 '05 #8
On 7 Aug 2005 17:31:02 -0700, "Jordan Rastrick" <jr*******@student.usyd.edu.au> wrote:
Good point. I suppose I'd only ever seen it implemented with the if
test, but you're right, the plain while loop should work fine. Silly
me.

def gcd(a,b):
while b != 0:
a, b = b, a%b
return a

Even nicer.

what is the convention for handling signed arguments? E.g.,
def gcd(a,b): ... while b != 0:
... a, b = b, a%b
... return a
... gcd(3, -12) -3 gcd(-12, 3)

3

Regards,
Bengt Richter
Aug 8 '05 #9

Erik the Red wrote:
So, I did the following:
---
a=input("Give me an integer")
b=input("Give me another integer")

def gcd(a,b):

if a < b:
a, b = b, a
while b != 0:
a, b = b, a % b
return a
---
But, in the xterm, it terminates after "Give me another integer."

Is Euclid's Algorithm supposed to be implemented in such a way as to be
used as a tool to find the GCD of two integers, or have I
misinterpreted the intent of the algorithm?


Personally, I would just use a math library that includes GCD and
probably does it more efficiently that I could. An example of
which is GMPY, the GNU Multiple Precision C library with a
Python wrapper.

But if I wanted to roll my own, I would implement the Extended
Euclidean Algorithm which produces some usefull information that
can be used to solve a Linear Congruence in addition to finding
the GCD. A Linear Congruence would be

X*A = Z (mod Y) where "=" means "is congruent to".

Given X, Y and Z, A can be solved IIF GCD(X,Y) divides Z. If you
use the Extended Euclidean Algorithm to find GCD(X,Y) you will
have the additional parameters needed to solve the Linear
Congruence (assuming it is solvable).

For example, I run into problems of the form

G = (X*A - Z)/Y

where I want to find an integer A such that G is also an integer
(X, Y and Z are integers). Lucky for me, the RHS can be directly
converted to a Linear Congruence: X*A = Z (mod Y). And in my
particular problems, X is always a power of 2 and Y always a
power of 3 so the GCD(X,Y) is always 1 which will always divide
Z meaning my problems are _always_ solvable.

And GMPY has a function that directly solves Linear Congruence:

divm(a,b,m): returns x such that b*x==a modulo m, or else raises
a ZeroDivisionError exception if no such value x exists
(a, b and m must be mpz objects, or else get coerced to mpz)

So the first integer solution to

35184372088832*A - 69544657471
------------------------------
19683

is
A=collatz_functions.gmpy.divm(69544657471,35184372 088832,19683)
A mpz(15242)

Checking,
G = divmod(35184372088832*15242-69544657471,19683)
G

(27245853265931L, 0L)

Of course, what the gods give they also take away. It turns out
that the GMPY divm() function has a bug (whether in the underlying
GMP C code or the Python wrapper I don't know). It has a memory
leak when called repeatedly with large numbers making it useless
to me. But I caught another lucky break. GMPY also provides a
modulo inverse function from which one can easily derive the
linear congruence. And this function doesn't exhibit the memory
leak.

But luck favors the prepared mind. I was able to come up with a
workaround because I had gone to the trouble of working up an
Extended Euclidean Algorithm prior to discovering that I didn't
need it. But during the course of which, I also learned about
modulo inverse which was the key to the workaround.

Aug 8 '05 #10
On 2005-08-08, Bengt Richter <bo**@oz.net> wrote:
On 7 Aug 2005 17:31:02 -0700, "Jordan Rastrick" <jr*******@student.usyd.edu.au> wrote:
Good point. I suppose I'd only ever seen it implemented with the if
test, but you're right, the plain while loop should work fine. Silly
me.

def gcd(a,b):
while b != 0:
a, b = b, a%b
return a

Even nicer.

what is the convention for handling signed arguments? E.g.,


As far as I understand the convention is it doesn't make
sense to talk about a gcd if not all numbers are positive.

I would be very interested if someone knows what the gcd
of 3 and -3 should/would be.

--
Antoon Pardon
Aug 14 '05 #11

Antoon Pardon wrote:
On 2005-08-08, Bengt Richter <bo**@oz.net> wrote:
On 7 Aug 2005 17:31:02 -0700, "Jordan Rastrick" <jr*******@student.usyd.edu.au> wrote:
Good point. I suppose I'd only ever seen it implemented with the if
test, but you're right, the plain while loop should work fine. Silly
me.

def gcd(a,b):
while b != 0:
a, b = b, a%b
return a

Even nicer.
what is the convention for handling signed arguments? E.g.,


As far as I understand the convention is it doesn't make
sense to talk about a gcd if not all numbers are positive.


That may well be the convention but I don't know why you say
it doesn't make sense. -3/3 still has a remainder of 0.
So does -3/-3, but 3 is greater than -3 so it "makes sense"
that the GCD will be positive.

I would be very interested if someone knows what the gcd
of 3 and -3 should/would be.
Someone has already decided what it should be.
from gmpy import *
help(gcd) Help on built-in function gcd:

gcd(...)
gcd(a,b): returns the greatest common denominator of numbers a and
b
(which must be mpz objects, or else get coerced to mpz)
gcd(3,-3)

mpz(3)
What would really be interesting is whether this conflicts with
any other implementation of GCD.

--
Antoon Pardon


Aug 14 '05 #12
Antoon Pardon wrote:
On 2005-08-08, Bengt Richter <bo**@oz.net> wrote:
On 7 Aug 2005 17:31:02 -0700, "Jordan Rastrick" <jr*******@student.usyd.edu.au> wrote:

Good point. I suppose I'd only ever seen it implemented with the if
test, but you're right, the plain while loop should work fine. Silly
me.

def gcd(a,b):
while b != 0:
a, b = b, a%b
return a

Even nicer.


what is the convention for handling signed arguments? E.g.,

As far as I understand the convention is it doesn't make
sense to talk about a gcd if not all numbers are positive.

I would be very interested if someone knows what the gcd
of 3 and -3 should/would be.


Within the integers, common definitions of gcd don't distinguish
positive from negative numbers, so if 3 is a gcd of x and y then
-3 is also a gcd. That's using a definition of gcd as something
like "g is a gcd of x and y if g|x and g|y and, for any h such
that h|x and h|y, h|g", i.e., a gcd is a common divisor and is
divisible by any other common divisor. The word "greatest" in
this context is wrt the partial ordering imposed by | ("divides").
(Note that "|" in the above is the mathematical use as a|b if
there is an (integral) c such that ac=b, i.e., b is divisible
by a. These definitions generalize to rings other than the
integers, without requiring a meaningful < comparison on the
ring.)

All of that said, it would be reasonable when working in the
integers to always report the positive value as the gcd, to
make gcd a simpler function. For some applications, it won't
matter if you choose positive or negative, so going positive
does no harm, and others might be simplified by assuming gcd>0.

-- James
Aug 14 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: DENG | last post by:
Hi, all I've used Python Bz2 module for times and want to kown something about Burrows-Wheeler (BWT) algorithm, the Bz2 module is wrriten in C, is there a version in Python too? BWT...
4
by: Kinsley Turner | last post by:
Hey-ho, I'm getting a bit out of my depth porting the 'tiny encryption algorithm' from C to python. Ref: http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm...
5
by: Bo Yang | last post by:
Hi , I have writen a python program to slove a problem described as below: (Forgive my poor English !) Put the 2^n 0 or 1 to form a ring , and we can select any continuous n ones from the...
5
by: Tor Erik | last post by:
I would be surprised if it is the naive: m = 0 s1 = "me" s2 = "locate me" s1len = len(s1) s2len = len(s2) found = False while m + s1len <= s2len:
5
by: chrisguest | last post by:
I am trying to write some code that will take a list of functional expressions, and order them so that those with primitive terms appear at the beginning of the list and those that are defined by...
22
by: Jia Lu | last post by:
Hi all. I want to create a large list like: aaaa ~ zzzz Is there any good algorithm to do this? Thanx Jia Lu
4
by: sdlt85 | last post by:
Hi, Can someone help me with an idea on how to start writing a C++ code for generating greatest common divisor and the linear combination of two intergers represented as gcd(m, n)= mx + ny and...
11
lotus18
by: lotus18 | last post by:
Hello experts The Euclid's Method: If u is greater then v then the greatest common divisor of u and v is the sum as the greatest common divisor of v and u-v. Now my question is, how can I...
32
by: =?ISO-8859-1?Q?Szabolcs_Horv=E1t?= | last post by:
I did the following calculation: Generated a list of a million random numbers between 0 and 1, constructed a new list by subtracting the mean value from each number, and then calculated the mean...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.