Re: [Python-es] suma de multiplos de 3 y 5

2018-09-05 Por tema Hector Muñoz
Creo que para solucionar este problema no es necesario ningún bucle.

Esta es la solución más simple que he podido encontrar:

from __future__ import division
def sumar_multiplos_k(a1, an,d):
n = an/d
S = ((a1+an)/2)*n

return S

print(sumar_multiplos_k(3,999,3)+sumar_multiplos_k(5,995,5)-sumar_multiplos_k(15,990,15))

El razonamiento es el siguiente:

Viendo la naturaleza del problema, tiene una pinta de progresión
aritmética que echa para atrás. Al final es encontrar la suma de los
múltiplos de 3 o de 5, es decir, suma de series cuyos elementos están
separados entre tres o cinco unidades, es decir, con razón 3 o 5.

La expresión de la progresión aritmética es:
((a1+an)/2)*n donde a1 es el primer elemento de la serie, an es el
último elemento de la serie y n el número total de elementos.

En esta expresión lo único que podemos desconocer es n, el número
total de elementos, pero si vamos a la expresión general de la
progresión podemos decir que
an = a1+(n-1)d donde a1 es el primer elemento, n el número total de
elementos y d la razón de la serie, es decir el número que debemos
sumar al elemento anterior para conseguir el próximo elemento.
De la expresión anterior tenemos todos los parámetros excepto n así
que se convierte es simplificar y resolver una ecuación de primer
grado.

El "quid" de la cuestión, creo yo, es en darse cuenta de lo siguiente:
Álgunos múltiplos de 3:
3,6,9,12,15,...,27,30,33,...,42,45,...
Algunos múltiplos de 5:
5,10,15,20,25,30,35,40,45,...

Si observamos 15,30,45 se repiten en ambas series por lo que si
sumasemos ambas progresiones estaríamos sumando los múltiplos de 15
dos veces. Por lo que a la suma de la progresión de 3 y la progresión
de 5 hay que restarle la progresión de 15. Y ese sería el resultado.

No he encontrado una forma más óptima de hacerlo, de esta forma nos
quitamos de encima los bucles y no hay que buscar optimizaciones con
cython ni nada parecido.

Saludos!

On Wed, 5 Sep 2018 at 06:55, AGTUGO  wrote:
>
> Después de ver los tiempos de ejecución obviamente aquellos métodos que 
> hicieron un for pues fueron más lentos, los que generaron los números para 
> ser sumados pues son los más rápidos, lo cual no es ninguna sorpresa. Creo 
> que la mayoría de la gente no busca velocidad en python pero hay casos donde 
> optimizaciones pequeñas hacen la diferencia, al final creo que lo mejor para 
> optimizar pues es escribir en c o en cython algunas funciones en particular. 
> Creo que mucho más fácil de mantener en cython. Prepararé una comparación de 
> todos los métodos aquí expuestos en cPython, pypy, adicionalmente numoy y 
> cython, para cerrar esta discusión y tratar de llegar a algo que pueda ser 
> referenciado en el futuro.
>
> On Tue, Sep 4, 2018 at 10:10 PM AGTUGO  wrote:
>>
>> Adicionalmente me gusta verlo como conjuntos A union B.
>>
>> def euler001_with_sets(n: int, multiples:Tuple[int]) -> int:
>> union_set = set()
>> all_sums_set = (set(range(0,n,mul)) for mul in multiples)
>> union_set = union_set.union(*all_sums_set)
>> return sum(union_set)
>>
>>
>>
>> On Tue, Sep 4, 2018 at 9:35 AM AGTUGO  wrote:
>>>
>>> Aquí lo único que haría para cualquier caso es sacar la comparación en una 
>>> funciòn para que no este tan hardcoded
>>>
>>> from typing import List, Tuple
>>>
>>> begin = 0
>>> end = 1000
>>> multiples= (3,5)
>>>
>>> """
>>> Esta función revisa si es divisible entre todos los multiplos propuestos 
>>> dentro del mundo
>>> de los naturales y retorna un booleano en caso de que así sea
>>> """
>>> def is_divisible(tb_divided:int, multiples: List[int]) -> bool:
>>> return any((tb_divided%mul == 0 for mul in multiples))
>>>
>>> def euler001(n: int, multiples:Tuple[int]) -> int:
>>> return sum(i for i in range(1, n) if is_divisible(i,multiples))
>>>
>>> print(euler001(end, multiples))
>>>
>>>
>>>
>>> On Tue, Sep 4, 2018 at 5:33 AM Chema Cortes  wrote:



 El lun., 3 sept. 2018 a las 21:12, AGTUGO () escribió:
>
> """
> Problema tomado de
> https://projecteuler.net/problem=1
>
>
> If we list all the natural numbers below 10 that are multiples
> of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
> Find the sum of all the multiples of 3 or 5 below 1000.
>
> Si listamos todos los numeros naturales menores a 10 que son
> múltiplos de 3 o 5 obtenemos 2, 5, 6 y 9. La suma de los múltiplos es 23.
> Encuentra la suma de los múltiplos de 3 o 5 menores de 1000.
>
>
> """
>
> """
> Este es mi aporte de código no esta diseñado para ser eficiente,
> el objetivo es jugar con el lenguaje. Ojalá puedan compartir
> una visión interesante de como resolver este problema.
> Si tienen una forma más eficiente de hacer el set o más elegante también 
> es bienvenido.
> Saludos.
> """
>
> import itertools
> begin = 0
> end = 1000
> multiples= (3,5)
>
> x = [range(begin,end,i) for i in multi

Re: [Python-es] suma de multiplos de 3 y 5

2018-09-05 Por tema AGTUGO
Claro están siempre las ecuaciones de sumatorias, el mejor método para este
caso, de hecho en euler lo comentan hasta el cansancio, en mi caso prefiero
buscar una soluciòn más del mundo del algoritmo que de las matematicas para
jugar con el lenguaje. Seguiré la idea de cython ya que me parece
interesante comparar. Claro podemos poner un problema después que solamente
se pueda resolver solamente con aproximaciones numéricas. El objetivo es
poder observar los diferentes mètodos para atacar el problema, en este caso
ya me había sorprendido que nadie lo hubiera sacado al tema. Saludos.
___
Python-es mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-es