Código para mayor divisor común en Python [cerrado]

108

El máximo común divisor (MCD) de ayb es el número más grande que los divide a ambos sin resto.

Una forma de encontrar el MCD de dos números es el algoritmo de Euclides, que se basa en la observación de que si res el resto cuando ase divide por b, entonces gcd(a, b) = gcd(b, r). Como caso base, podemos usar gcd(a, 0) = a.

Escribir una llamada mcd función que toma parámetros ay bdevuelve su máximo común divisor.

Luke D
fuente

Respuestas:

300

Está en la biblioteca estándar .

>>> from fractions import gcd
>>> gcd(20,8)
4

Código fuente del inspectmódulo en Python 2.7:

>>> print inspect.getsource(gcd)
def gcd(a, b):
    """Calculate the Greatest Common Divisor of a and b.

    Unless b==0, the result will have the same sign as b (so that when
    b is divided by it, the result comes out positive).
    """
    while b:
        a, b = b, a%b
    return a

A partir de Python 3.5, gcd está en el mathmódulo ; el que fractionsestá en está obsoleto. Además, inspect.getsourceya no devuelve código fuente explicativo para ninguno de los métodos.

usuario545424
fuente
3
No devuelve "el número _más grande_ que divide a ambos sin resto" , por ejemplo, fractions.gcd(1, -1)es , -1pero es 1 > -1decir, 1divide a ambos 1y -1sin resto y es más grande que -1, consulte bugs.python.org/issue22477
jfs
1
@JFSebastian No veo esto como un problema ... solo mira el comentario en el código fuente: "A menos que b == 0, el resultado tendrá el mismo signo que b" , por lo gcd(1, -1) == -1que me parece totalmente legítimo.
Marco Bonelli
@MarcoBonelli: sí. Se comporta como está documentado, pero no es la definición de libro de texto con la que la mayoría de la gente está familiarizada. Lea la discusión que he vinculado anteriormente . Personalmente, me gusta fractions.gcd()como está (funciona en elementos de anillo euclidianos).
jfs
1
@JFSebastian FWIW, a partir de Python 3.5, math.gcd(1, -1)regresa 1.
Acumenus
1
@ABB math.gcd () y fracciones.gcd () son diferentes como se dice en la respuesta y los comentarios.
jfs
39

Los algoritmos con mn pueden durar mucho.

Este funciona mucho mejor:

def gcd(x, y):
    while y != 0:
        (x, y) = (y, x % y)
    return x
netom
fuente
5
Este también es el de la biblioteca estándar.
sayantankhan
10
¿Cómo funciona ese algoritmo? es como magia.
Dooderson
20
@netom: no, la tarea no se puede escribir así; la asignación de tupla utiliza xantes de ser asignada. Que ha asignado ya x la primera , por lo que ahora yse va a establecer en 0(como y % ysiempre es 0).
Martijn Pieters
1
@MartijnPieters sí, tienes razón, debería haber usado una variable temporal. así: x_ = y; y = x% y; x = x_
netom
3
@netom: que no es necesario en absoluto cuando se usa una asignación de tupla como se hace en esta respuesta.
Martijn Pieters
18

Esta versión de código utiliza el algoritmo de Euclid para encontrar GCD.

def gcd_recursive(a, b):
    if b == 0:
        return a
    else:
        return gcd_recursive(b, a % b)
Ankush
fuente
28
Usó iter en el nombre, pero en realidad es una versión recursiva.
Shiplu Mokaddim
la recursividad es poco eficiente en comparación con las versiones de bucle, + debe llamarlo con b> a
Dr. Goulu
1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
Andreas K.
16
gcd = lambda m,n: m if not n else gcd(n,m%n)
Jonas Byström
fuente
3
def gcd(m,n):
    return gcd(abs(m-n), min(m, n)) if (m-n) else n
dansalmo
fuente
5
Nunca use "es" cuando quiera comparar por igualdad. La caché de números enteros pequeños es un detalle de implementación de CPython.
Marius Gedminas
2

Solución muy concisa usando recursividad:

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a%b)
preetika mondal
fuente
2

usando recursividad ,

def gcd(a,b):
    return a if not b else gcd(b, a%b)

usando mientras ,

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

usando lambda,

gcd = lambda a,b : a if not b else gcd(b, a%b)

>>> gcd(10,20)
>>> 10
Mohideen bin Mohammed
fuente
1
La versión lambda no puede funcionar porque no tiene ninguna condición para detener la recursividad. Creo que solo está llamando a su función previamente definida.
rem
1
a=int(raw_input('1st no \n'))
b=int(raw_input('2nd no \n'))

def gcd(m,n):
    z=abs(m-n)
    if (m-n)==0:
        return n
    else:
        return gcd(z,min(m,n))


print gcd(a,b)

Un enfoque diferente basado en el algoritmo de Euclid.


fuente
1
def gcdRecur(a, b):
    '''
    a, b: positive integers

    returns: a positive integer, the greatest common divisor of a & b.
    '''
    # Base case is when b = 0
    if b == 0:
        return a

    # Recursive case
    return gcdRecur(b, a % b)
Vergüenzas
fuente
1

Creo que otra forma es usar la recursividad. Aquí está mi código:

def gcd(a, b):
    if a > b:
        c = a - b
        gcd(b, c)
    elif a < b:
        c = b - a
        gcd(a, c)
    else:
        return a
dexhunter
fuente
No regresa después de las llamadas recursivas ... intente ejecutar gcd(10,5)...
Tomerikoo
0

en python con recursividad:

def gcd(a, b):
    if a%b == 0:
        return b
    return gcd(b, a%b)
keajer
fuente
0
def gcd(a,b):
    if b > a:
        return gcd(b,a)
    r = a%b
    if r == 0:
        return b
    return gcd(r,b)
dpeleg2000
fuente
0

Para a>b:

def gcd(a, b):

    if(a<b):
        a,b=b,a
        
    while(b!=0):
        r,b=b,a%r
        a=r
    return a

Para cualquiera a>bo a<b:

def gcd(a, b):

    t = min(a, b)

    # Keep looping until t divides both a & b evenly
    while a % t != 0 or b % t != 0:
        t -= 1

    return t
Rao Baswaraj
fuente
4
intercambio de variables entre Python es que los niños jueguen: b, a = a, b. intente leer más sobre el idioma
Jason Hu
3
Me gusta lo que dices, pero no me gusta la forma en que lo dices
JackyZhu
0

Tuve que hacer algo como esto para una tarea con bucles while. No es la forma más eficiente, pero si no desea utilizar una función, esto funciona:

num1 = 20
num1_list = []
num2 = 40
num2_list = []
x = 1
y = 1
while x <= num1:
    if num1 % x == 0:
        num1_list.append(x)
    x += 1
while y <= num2:
    if num2 % y == 0:
        num2_list.append(y)
    y += 1
xy = list(set(num1_list).intersection(num2_list))
print(xy[-1])
Vanessa
fuente
0
def _grateest_common_devisor_euclid(p, q):
    if q==0 :
        return p
    else:
        reminder = p%q
        return _grateest_common_devisor_euclid(q, reminder)

print(_grateest_common_devisor_euclid(8,3))
Sai prateek
fuente
-1

Este código calcula el mcd de más de dos números dependiendo de la elección dada por # el usuario, aquí el usuario da el número

numbers = [];
count = input ("HOW MANY NUMBERS YOU WANT TO CALCULATE GCD?\n")
for i in range(0, count):
  number = input("ENTER THE NUMBER : \n")
  numbers.append(number)
numbers_sorted = sorted(numbers)
print  'NUMBERS SORTED IN INCREASING ORDER\n',numbers_sorted
gcd = numbers_sorted[0]

for i in range(1, count):
  divisor = gcd
  dividend = numbers_sorted[i]
  remainder = dividend % divisor
  if remainder == 0 :
  gcd = divisor
  else :
    while not remainder == 0 :
      dividend_one = divisor
      divisor_one = remainder
      remainder = dividend_one % divisor_one
      gcd = divisor_one

print 'GCD OF ' ,count,'NUMBERS IS \n', gcd
Prashant
fuente
5
¡Bienvenido a Stack Overflow! ¿Consideraría agregar algo de narrativa para explicar por qué funciona este código y qué lo convierte en una respuesta a la pregunta? Esto sería muy útil para la persona que hace la pregunta y para cualquier otra persona que se presente.
Andrew Barber
-1

El intercambio de valor no funcionó bien para mí. Así que configuré una situación similar a un espejo para los números que se ingresan en a <b O a> b:

def gcd(a, b):
    if a > b:
        r = a % b
        if r == 0:
            return b
        else:
            return gcd(b, r)
    if a < b:
        r = b % a
        if r == 0:
            return a
        else:
            return gcd(a, r)

print gcd(18, 2)
troychroi
fuente
2
Esta ni siquiera es una sintaxis válida de Python. La sangría es importante.
Marius Gedminas
2
¿Qué pasa cuando a = b? debe tener una condición IF inicial para detectar esto.
josh.thomson
-2
#This program will find the hcf of a given list of numbers.

A = [65, 20, 100, 85, 125]     #creates and initializes the list of numbers

def greatest_common_divisor(_A):
  iterator = 1
  factor = 1
  a_length = len(_A)
  smallest = 99999

#get the smallest number
for number in _A: #iterate through array
  if number < smallest: #if current not the smallest number
    smallest = number #set to highest

while iterator <= smallest: #iterate from 1 ... smallest number
for index in range(0, a_length): #loop through array
  if _A[index] % iterator != 0: #if the element is not equally divisible by 0
    break #stop and go to next element
  if index == (a_length - 1): #if we reach the last element of array
    factor = iterator #it means that all of them are divisibe by 0
iterator += 1 #let's increment to check if array divisible by next iterator
#print the factor
print factor

print "The highest common factor of: ",
for element in A:
  print element,
print " is: ",

mayor_devisor_común (A)

usuario4713071
fuente
-2
def gcdIter(a, b):
gcd= min (a,b)
for i in range(0,min(a,b)):
    if (a%gcd==0 and b%gcd==0):
        return gcd
        break
    gcd-=1
Par bas
fuente
Esta es la forma más fácil ... ¡No lo pongas difícil!
Par bas
3
Gracias por proporcionar código que podría ayudar a resolver el problema, pero en general, las respuestas son mucho más útiles si incluyen una explicación de lo que se pretende que haga el código y por qué eso resuelve el problema.
Neuron
1
Este código está incompleto (sin declaración de devolución final) y con un formato incorrecto (sin sangría). Ni siquiera estoy seguro de qué breakintenta lograr esa declaración.
kdopen
-2

Aquí está la solución que implementa el concepto de Iteration:

def gcdIter(a, b):
    '''
    a, b: positive integers

    returns: a positive integer, the greatest common divisor of a & b.
    '''
    if a > b:
        result = b
    result = a

    if result == 1:
        return 1

    while result > 0:
        if a % result == 0 and b % result == 0:
            return result
        result -= 1
Bikramjeet Singh
fuente