Esta é a maneira muito estúpida:
def divisorGenerator(n):
for i in xrange(1,n/2+1):
if n%i == 0: yield i
yield n
O resultado que gostaria de obter é semelhante a este, mas gostaria de um algoritmo mais inteligente (este é muito lento e burro :-)
Posso encontrar os fatores primos e sua multiplicidade com rapidez suficiente. Tenho um gerador que gera fator desta forma:
(fator1, multiplicidade1)
(fator2, multiplicidade2)
(fator3, multiplicidade3)
e assim por diante ...
ou seja, a saída de
for i in factorGenerator(100):
print i
é:
(2, 2)
(5, 2)
Não sei o quanto isso é útil para o que quero fazer (codifiquei para outros problemas), de qualquer forma, gostaria de uma maneira mais inteligente de fazer
for i in divisorGen(100):
print i
envie este:
1
2
4
5
10
20
25
50
100
ATUALIZAÇÃO: Muito obrigado a Greg Hewgill e seu "jeito inteligente" :) Calculando todos os divisores de 100000000 levou 0,01s com seu caminho contra os 39s que o modo idiota pegou na minha máquina, muito legal: D
ATUALIZAÇÃO 2: Pare de dizer que esta é uma duplicata desta postagem. Calcular o número do divisor de um determinado número não precisa calcular todos os divisores. É um problema diferente, se você acha que não é, então procure por "Função Divisor" na wikipedia. Leia as perguntas e a resposta antes de postar, se você não entende qual é o assunto, simplesmente não acrescente respostas inúteis e já dadas.
Respostas:
Dada a sua
factorGenerator
função, aqui está umdivisorGen
que deve funcionar:A eficiência geral desse algoritmo dependerá inteiramente da eficiência do
factorGenerator
.fonte
Para expandir o que Shimi disse, você deve executar seu loop apenas de 1 até a raiz quadrada de n. Então, para encontrar o par, faça
n / i
, e isso cobrirá todo o espaço do problema.Como também foi observado, este é um problema NP, ou 'difícil'. A busca exaustiva, da maneira como você a está fazendo, é tão boa quanto possível para respostas garantidas. Esse fato é usado por algoritmos de criptografia e similares para ajudar a protegê-los. Se alguém resolvesse este problema, a maior parte, senão toda a nossa comunicação 'segura' atual, se tornaria insegura.
Código Python:
Que deve gerar uma lista como:
fonte
Embora já existam muitas soluções para isso, eu realmente tenho que postar isso :)
Esta está:
Código:
fonte
while i*i <= nn
porwhile i <= limit
, ondelimit = math.sqrt(n)
Eu acho que você pode parar em
math.sqrt(n)
vez de n / 2.Vou dar um exemplo para que você possa entender facilmente. Agora o
sqrt(28)
é5.29
por issoceil(5.29)
será 6. Então, eu se eu vou parar em 6 então eu pode obter todos os divisores. Quão?Primeiro veja o código e depois a imagem:
Agora, veja a imagem abaixo:
Digamos que eu já tenha adicionado
1
à minha lista de divisores e comece comi=2
issoPortanto, no final de todas as iterações, conforme adicionei o quociente e o divisor à minha lista, todos os divisores de 28 são preenchidos.
Fonte: Como determinar os divisores de um número
fonte
math.sqrt(n) instead of n/2
é obrigatório para a elegânciaGosto da solução de Greg, mas gostaria que fosse mais parecida com python. Acho que seria mais rápido e legível; então, depois de algum tempo codificando, descobri isso.
As duas primeiras funções são necessárias para fazer o produto cartesiano das listas. E pode ser reutilizado sempre que houver esse problema. A propósito, tive que programar sozinho, se alguém souber de uma solução padrão para esse problema, sinta-se à vontade para entrar em contato comigo.
"Factorgenerator" agora retorna um dicionário. E então o dicionário é alimentado em "divisores", que o usa para gerar primeiro uma lista de listas, onde cada lista é a lista dos fatores da forma p ^ n com p '. Em seguida, fazemos o produto cartesiano dessas listas e, finalmente, usamos a solução de Greg para gerar o divisor. Nós os classificamos e os devolvemos.
Eu testei e parece ser um pouco mais rápido que a versão anterior. Eu testei como parte de um programa maior, então não posso dizer o quanto é mais rápido.
Pietro Speroni (pietrosperoni dot it)
PS, é a primeira vez que estou postando no stackoverflow. Estou ansioso por qualquer feedback.
fonte
Esta é uma maneira inteligente e rápida de fazer isso para números até e cerca de 10 ** 16 no Python 3.6 puro,
fonte
Adaptado do CodeReview , aqui está uma variante que funciona com
num=1
!fonte
NameError: global name 'prime_factors' is not defined
. Nenhuma das outras respostas, nem a pergunta original, define o que isso faz.Vou apenas adicionar uma versão ligeiramente revisada do Anivarth (como acredito que seja a mais pítônica) para referência futura.
fonte
Velha pergunta, mas aqui está minha opinião:
Você pode fazer proxy com:
NOTA: Para idiomas que suportam, isso pode ser recursivo.
fonte
Supondo que a
factors
função retorne os fatores de n (por exemplo,factors(60)
retorna a lista [2, 2, 3, 5]), aqui está uma função para calcular os divisores de n :fonte
Aqui está minha solução. Parece ser burro, mas funciona bem ... e eu estava tentando encontrar todos os divisores adequados, então o loop começou em i = 2.
fonte
Se você só se preocupa em usar as compreensões de lista e nada mais importa para você!
fonte
Se o seu PC tem muita memória, uma única linha bruta pode ser rápida o suficiente com numpy:
Demora menos de 1 segundo no meu PC lento.
fonte
Minha solução via função de gerador é:
fonte
fonte
Para mim, isso funciona bem e também é limpo (Python 3)
Não é muito rápido, mas retorna os divisores linha por linha conforme desejado. Você também pode fazer list.append (n) e list.append (número) se realmente quiser
fonte