Euler 5 (Python)

Enunciado 5

2520 es el menor número que puede ser dividido sin resto por todos los números de 1 a 10.

¿Cuál es el menor número que que puede dividirse sin resto por todos los números de 1 a 20?

Solución

La solución fue obtenida ejecutando el siguiente programa Python 2.5.2:

from math import sqrt
from operator import mul, add
 
def primo(n):
    for i in xrange(2,int(sqrt(n))+1):
        if n % i == 0:
            return False
    return True
 
def factorizar(n):
    primos = [x for x in xrange(2,n+1) if primo(x)]
    factores = []
    if n == 1:
        return [1]
    for p in primos:
        if n == p:
                factores.append(p)
                return factores
        if n % p == 0:
                n /= p
                factores.append(p)
                while n % p == 0:
                    n /= p
                    factores.append(p)
    return factores
 
def mcm(l):
    '''Maximo comun multiplo'''
    ff = [factorizar(i) for i in l]
    singles = list(set(reduce(add,ff)))
    temp = []
    for s in singles:
        temp.extend([s] * max([f.count(s) for f in ff]))
    return reduce(mul,temp,1)
 
if __name__ == '__main__':
    #print mcm(range(1,11))
    print mcm(range(1,21))

Python tips

  • El módulo operator tiene varias funciones útiles equivalentes a operadores como * y + que pueden utilizarse con funciones como reduce, cuyo primer parámetro es una función.
  • reduce toma una función f de dos argumentos y una lista l. Aplica f a los dos primeros elementos de la lista y obtiene un resultado, luego aplica la función f al resultado con el tercer elemento de la lista, y así sucesivamente hasta consumir toda la lista y retornar el resultado final. Opcionalmente se le puede pasar un tercer parámetro para que la primer llamada a la función f sea aplicada sobre este y el primer elemento de la lista.

About Juanjo

Mi nombre es Juanjo Conti, vivo en Santa Fe y soy Ingeniero en Sistemas de Información. Mi lenguaje de programación de cabecera es Python; lo uso para trabajar, estudiar y jugar. Como hobby escribí un libro de cuentos que se puede descargar gratuitamente.
This entry was posted in Aprendiendo Python, Problemas and tagged , . Bookmark the permalink.
  • Matias

    Esta variante es algo más corta y bastante más rápida, aunque con los números de 1 a 20 no se nota. Se basa en que mcm(a,b) = a*b/mcd(a,b), y en el Algoritmo de Euclides para calcular el mcd (esto es lo que para números grandes lo hace mucho más rápido que factorizar).

    >>> def mcd(a,b):
    ...     a,b = max(abs(a),abs(b)),min(abs(a),abs(b));
    ...     while b>0:
    ...             a,b = b,a%b
    ...     return a
    ... 
     
    >>> def mcm(a,b):
    ...     return abs(a)*abs(b)/mcd(a,b)
    ... 
     
    >>> reduce(mcm,range(1,21))
    232792560L
  • Juanjo

    Excelsus!