Pues que puedo decir, el día de ayer me he enterado del reto de Perl 6 2011 y simplemente no pude dejar de pensar en como podría ser resuelto usando Python, este consta de 5 tareas a resolver y sólo como mero reto personal he decidido hacer la segunda tarea.

== Sum of cubes

Some natural numbers can be as the sum of two positive cubes of natural
numbers. For example, 1729 is 12 cubed plus 1 cubed. Some natural numbers
can even be expressed as more than one such sum. For example, 1729 can
also be expressed as 10 cubed plus 9 cubed.

Just for clarity's sake, the sum with the two terms reversed is the
same sum, not a new one. Thus, 91 is 3 cubed plus 4 cubed, but
finding "4 cubed plus 3 cubed" does not count as a distinct sum.

Write a program that accepts an integer N on the command line, and
prints out the first N of these numbers in increasing order. For each
number found, print it out, as well as the sums of cubes that yield that
number.

For example:

    1729 = 12 ** 3 + 1 ** 3 = 10 ** 3 + 9 ** 3

Y mi solución es la siguiente

import sys
from decimal import Decimal
from fractions import Fraction

# Show help
def usage():
    print 'Sintaxis:'
    print 'sumofcubes.py N'
    print
    print 'Where N is un natural number'
    print

# Get solutions (x,y) by n = x**3 + y**3
def sumofcubes(n):
    solutions = []
    x = 1
    xc = x**3
    while xc < n:
        yc = n - xc
        y = round(Decimal(yc ** Fraction('1/3')),6)
        if y.is_integer() and {x,y} not in solutions:
            # print n, x, y
            solutions.append({x,y})
        x += 1
        xc = x**3
    return solutions

def main(argv):
    # Valid args
    if len(argv) != 2:
        usage()
        sys.exit(1)

    n = int(argv[1])

    # Search number on interval [0,n]
    for i in range(n+1):
        sol = sumofcubes(i)
        # If get 2 o more solutions print results
        if len(sol) >=2:
            par0 = list(sol[0])
            par1 = list(sol[1])
            print i,'= '+str(int(par0[0]))+'**3 + '+str(int(par0[1]))+'**3 = '+str(int(par1[0]))+'**3 + '+str(int(par1[1]))+'**3'

    print
    print 'Terminado!'

Una ejecución con n=100,000 se observa así

además he usado el comando time para determinar un aproximado del tiempo que ha tardado en encontrar todos los números y ha sido de 2m 41s, nada despreciable para mi laptop.

El otro día platicando con @mromtz teníamos en discusión el tema de la eficiencia de python para ambientes del alta concurrencia y en apariencia llegaría un punto en el que python y no daría el ancho y habría que usar algo diferente, sin embargo yo todavía tengo mis dudas (como es de esperarse siii).

Me gustaría conocer si alguien realiza este reto en perl y cual es su resultado, o si alguien más lo realiza en python y logra obtener un código más eficiente… ¿alguien podrá?

Anuncios