Esta es la forma más tonta:
def divisorGenerator(n):
for i in xrange(1,n/2+1):
if n%i == 0: yield i
yield n
El resultado que me gustaría obtener es similar a este, pero me gustaría un algoritmo más inteligente (este es demasiado lento y tonto :-)
Puedo encontrar factores primos y su multiplicidad lo suficientemente rápido. Tengo un generador que genera factor de esta manera:
(factor1, multiplicidad1)
(factor2, multiplicidad2)
(factor3, multiplicidad3)
y así sucesivamente ...
es decir, la salida de
for i in factorGenerator(100):
print i
es:
(2, 2)
(5, 2)
No sé cuánto es esto útil para lo que quiero hacer (lo codifiqué para otros problemas), de todos modos me gustaría una forma más inteligente de hacer
for i in divisorGen(100):
print i
salida esto:
1
2
4
5
10
20
25
50
100
ACTUALIZACIÓN: Muchas gracias a Greg Hewgill y su "manera inteligente" :) Calcular todos los divisores de 100000000 tomó 0.01s con su camino contra los 39s que el modo tonto tomó en mi máquina, muy bueno: D
ACTUALIZACIÓN 2: Deja de decir que esto es un duplicado de esta publicación. Calcular el número de divisores de un número dado no necesita calcular todos los divisores. Es un problema diferente, si cree que no lo es, busque "Función divisor" en wikipedia. Lea las preguntas y la respuesta antes de publicar, si no entiende cuál es el tema, simplemente no agregue respuestas que no sean útiles y que ya hayan dado.
Respuestas:
Dada su
factorGenerator
función, aquí hay unadivisorGen
que debería funcionar:La eficiencia general de este algoritmo dependerá completamente de la eficiencia del
factorGenerator
.fuente
Para ampliar lo que ha dicho Shimi, solo debe ejecutar su ciclo desde 1 hasta la raíz cuadrada de n. Luego, para encontrar el par, hazlo
n / i
, y esto cubrirá todo el espacio del problema.Como también se señaló, este es un problema NP o "difícil". La búsqueda exhaustiva, la forma en que la está haciendo, es tan buena como puede obtener respuestas garantizadas. Este hecho es utilizado por algoritmos de cifrado y similares para ayudar a protegerlos. Si alguien resolviera este problema, la mayor parte, si no toda, de nuestra comunicación "segura" actual se volvería insegura.
Código Python:
Que debería generar una lista como:
fuente
Aunque ya hay muchas soluciones para esto, realmente tengo que publicar esto :)
Este es:
Código:
fuente
while i*i <= nn
porwhile i <= limit
, dondelimit = math.sqrt(n)
Creo que puedes detenerte en
math.sqrt(n)
lugar de n / 2.Te daré un ejemplo para que lo entiendas fácilmente. Ahora el
sqrt(28)
es5.29
tanceil(5.29)
será 6. Entonces, si me detengo en 6, entonces puedo obtener todos los divisores. ¿Cómo?Primero vea el código y luego vea la imagen:
Ahora, vea la imagen a continuación:
Digamos que ya he añadido
1
a mi lista de divisores y comienzo coni=2
por loEntonces, al final de todas las iteraciones, ya que agregué el cociente y el divisor a mi lista, se completan todos los divisores de 28.
Fuente: Cómo determinar los divisores de un número.
fuente
math.sqrt(n) instead of n/2
es obligatorio para la eleganciaMe gusta la solución de Greg, pero desearía que fuera más como una pitón. Siento que sería más rápido y más legible; así que después de un tiempo de codificación salí con esto.
Las dos primeras funciones son necesarias para hacer el producto cartesiano de listas. Y se puede reutilizar siempre que surja este problema. Por cierto, tuve que programarlo yo mismo, si alguien conoce una solución estándar para este problema, no dude en ponerse en contacto conmigo.
"Factorgenerator" ahora devuelve un diccionario. Y luego el diccionario se alimenta a "divisores", quienes lo usan para generar primero una lista de listas, donde cada lista es la lista de los factores de la forma p ^ n con p primo. Luego hacemos el producto cartesiano de esas listas y finalmente usamos la solución de Greg para generar el divisor. Los clasificamos y los devolvemos.
Lo probé y parece ser un poco más rápido que la versión anterior. Lo probé como parte de un programa más grande, así que realmente no puedo decir cuánto es más rápido.
Pietro Speroni (pietrosperoni dot it)
PD: es la primera vez que publico en stackoverflow. Espero cualquier comentario.
fuente
Aquí hay una forma inteligente y rápida de hacerlo para números de hasta 10 ** 16 en Python 3.6 puro,
fuente
Adaptado de CodeReview , aquí hay una variante que funciona con
num=1
!fuente
NameError: global name 'prime_factors' is not defined
. Ninguna de las otras respuestas, ni la pregunta original, define qué hace esto.Solo voy a agregar una versión ligeramente revisada de Anivarth (ya que creo que es la más pitónica) para referencia futura.
fuente
Antigua pregunta, pero aquí está mi opinión:
Puede proxy con:
NOTA: Para los idiomas que lo admiten, esto podría ser una cola recursiva.
fuente
Suponiendo que la
factors
función devuelve los factores de n (por ejemplo,factors(60)
devuelve la lista [2, 2, 3, 5]), aquí hay una función para calcular los divisores de n :fuente
Esta es mi solución. Parece ser tonto pero funciona bien ... y estaba tratando de encontrar todos los divisores adecuados para que el ciclo comenzara desde i = 2.
fuente
¡Si solo le importa usar listas por comprensión y nada más le importa!
fuente
Si su PC tiene toneladas de memoria, una sola línea bruta puede ser lo suficientemente rápida con numpy:
Toma menos de 1 segundo en mi PC lenta.
fuente
Mi solución a través de la función del generador es:
fuente
fuente
Para mí, esto funciona bien y también está limpio (Python 3)
No es muy rápido, pero devuelve divisores línea por línea como desee, también puede hacer list.append (n) y list.append (number) si realmente lo desea
fuente