[pyar] Numeros primos

claudio canepa ccanepacc en gmail.com
Vie Nov 25 00:10:09 ART 2011


2011/11/24 Pablo M. Mana <pablo.m.mana en gmail.com>

> El otro dia en la CDC/SoL Fisa comento que los compresores son un
> herramienta muy poderosa en algunos casos.
> Y aca por una duda de bucles  se estaba hablando de numeros primos,
> Walter R. Ojeda Valiente comento algunas cosas que no sabia de como
> buscar en forma mas eficiente miembros de esta familia de numeros.
> Nunca hice nada con programacion funcional y este es mi primer
> intento. ¿Alguien se anima a miralo y decirme donde esta el error ?,
> la lista p1 deberia contener primos pero hay algun problema con el for
> anidado.
>
>
> def primos (inicio = 3, fin = 100 ):
> #""" Halla numeros primos por encima de 7 """
>    im = [ ( 2 * n + 1 ) for n in range (inicio, fin) ]
>    l1 = [ o for o in impares if (o % 5 != 0 ) ]
>    l2 = [ m for m in l1 if ( ( pow( m, 0.5) ) !=  int( pow( m, 0.5)))]
>    p1 = [ n for n in l2 if (l for l in range(2, int( pow( m, 0.5)))
> if n%l != 0 )]
>
> print impares
> print "*************************************************************"
> print l1
> print "*************************************************************"
> print l2
> print "*************************************************************"
> print p1
>
> Gracias
> Pablo M. Mana
> _______________________________________________
>

La linea p1 = ...
me parece que no hace lo que vos querés, por mas de un motivo:

Entiendo que tu intento alli es, para cada numero n impar no divisible por
cinco que vas a probar, generas la lista o set de numeros mayor que dos que
divide a n; si la lista tiene tamaño cero lo declaras primo.

Pero, (l for l range(10)) no es lista ni set; es un generador:
>>> z = (l for l in range(10))
>>> z
6: <generator object <genexpr> at 0x00CED990>
>>> bool(z)
7: True

entoces ese primer if te da siempre True.

Asi que para funcionar habria que transformar la linea en
   p1 = [ n for n in l2 if [l for l in range(2, int( pow( m, 0.5))) if n%l
!= 0 )] ]

por otro lado, la lista interna que queres calcular deberia acumular los
valores que dividen n, asi que la ultima condicion no deberia estar negada,
te quedaria

   p1 = [ n for n in l2 if (l for l in range(2, int( pow( m, 0.5))) if n%l
== 0 )]

Pienso que podes expresar esa linea mas claramente usando la funcion
all(<iterable>) -> bool ; verdadera si todos los valores en el iterable son
verdaderos.

Quedaria

   p1 = [ n for n in l2 if all(n%l != 0 for l in range(2, int( pow( m,
0.5))) ]

No criticos, pero ineficientes, es que hay un par de limites demasiado
grandes.

Hay igual maneras mas eficientes de escribir una funcion asi, haciendo uso
de que:

   - cuando avanzas hacia fin vos vas conociendo los primeros primos
   - p es primo si y solo si existe q primo, 1<q<sqrt(p) tal que q divide a
p
Pero tenes que pensarlo antes de empezar a escribir codigo.

--
claudio
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20111125/1acbf927/attachment.html>


More information about the pyar mailing list