Algoritmo para calcular o número de divisores de um determinado número

177

Qual seria o algoritmo mais ideal (em termos de desempenho) para calcular o número de divisores de um determinado número?

Seria ótimo se você pudesse fornecer pseudocódigo ou um link para algum exemplo.

EDIT: Todas as respostas foram muito úteis, obrigado. Estou implementando a peneira de Atkin e depois vou usar algo semelhante ao que Jonathan Leffler indicou. O link postado por Justin Bozonier tem mais informações sobre o que eu queria.

esquiador
fonte
Dadas as suas solicitações, o número de fatores é vago. Suponho que você esteja procurando o número de divisores primos não exclusivos, porque, se você não quiser que eu codifique, escreva um programa para sempre retornar 1 se o número a ser fator for um e 2 se for qualquer outra coisa. 0 pode precisar de uma mudança ...
Justin Bozonier
@ker: Existe uma gama de valores para os quais você precisa dos divisores. Existem muitas maneiras de calcular os fatores, e cada método é mais adequado a um intervalo específico.
Ande Turner 30/10/08
2
Aqui está um interessante problema relacionado projecteuler.net/problem=12
daniloquio
1
A ingestão de Peneira de Atkin, mesmo a partir do artigo editado da Wikipedia, nunca será mais rápida que uma Peneira de Eratóstenes com fator máximo de roda, até enormes limites impraticáveis, e as versões segmentadas de página são ainda mais favoráveis ​​ao SoE (consulte SoE primesieve versus SoA primegen como .. implementado pelo parceiro da Atkin Bernstein é do conhecimento Internet incorreta comum que o seu estudo provou SoA mais rápido, mas eles limitaram artificialmente a otimização do SoE usado para provar isso Ver minha resposta SoA para mais explicações
GordonBGood

Respostas:

78

Dmitriy está certo de que você desejará que a Peneira de Atkin gere a lista principal, mas não creio que isso cuide de toda a questão. Agora que você tem uma lista de números primos, precisará ver quantos desses números atuam como divisores (e com que frequência).

Aqui está um pouco de python para o algo. Olhe aqui e pesquise "Subject: math - need divisors algoritm". Apenas conte o número de itens na lista, em vez de devolvê-los.

Aqui está um Dr.Math que explica exatamente o que você precisa fazer matematicamente.

Essencialmente, tudo se resume a se o seu número né:
n = a^x * b^y * c^z
(onde a, bec são os divisores primos de n e x, ye z são o número de vezes que o divisor é repetido), a contagem total de todos os divisores é:
(x + 1) * (y + 1) * (z + 1).

Edit: BTW, para encontrar a, b, c, etc, você vai querer fazer o que equivale a algo ganancioso se eu estiver entendendo isso corretamente. Comece com o seu maior divisor principal e multiplique-o sozinho até que uma multiplicação adicional exceda o número n. Em seguida, vá para o próximo fator mais baixo e multiplique o número primo anterior ^ número de vezes que foi multiplicado pelo número primo atual e continue multiplicando pelo número primo até que o próximo exceda n ... etc. Acompanhe o número de vezes que você multiplica o número primo. divisores juntos e aplique esses números na fórmula acima.

Não tenho 100% de certeza da minha descrição de algo, mas se não for, é algo semelhante.

Justin Bozonier
fonte
1
Se você está fatorando um número grande, não precisa nem olhar para a lista principal. Você deseja eliminar toda a gama de possibilidades o mais rápido possível! Veja minha resposta para mais.
user11318
Sei que isso foi há 2 anos, mas seu link de algo python está quebrado, por acaso sabe onde ele existe agora?
jb.
2
Assim n = (a^x * b^y * c^z)-(x + 1) * (y + 1) * (z + 1)é a regra #
SIslam
1
Como o @Shashank diz, o algoritmo na seção "EDIT:" está errado: Suponha que n = 45 = 3 * 3 * 5. O maior divisor principal é 5, mas multiplicá-lo por si só até exceder n faria com que o algoritmo relate que possui 2 cópias do fator 5 (desde 5 * 5 = 25 <45).
Jrandom_hacker
1
O 'Sieve of Atkin' tem uma complexidade de tempo de execução de O (N / log (log (N))) na melhor das hipóteses. A verificação de força bruta em todos os divisores possíveis de 1 ... Sqrt (n) possui uma complexidade de tempo de execução de O (Sqrt (N)), que é muito superior. Como é que esta resposta foi aceita?
le_m
47

Existem muito mais técnicas de factoring do que a peneira de Atkin. Por exemplo, suponha que desejamos fatorar 5893. Bem, seu sqrt é 76,76 ... Agora, tentaremos escrever 5893 como um produto de quadrados. Bem (77 * 77 - 5893) = 36, que é 6 ao quadrado, então 5893 = 77 * 77 - 6 * 6 = (77 + 6) (77-6) = 83 * 71. Se isso não tivesse funcionado, teríamos analisado se 78 * 78 - 5893 era um quadrado perfeito. E assim por diante. Com essa técnica, você pode testar rapidamente fatores próximos à raiz quadrada de n muito mais rapidamente do que testando primos individuais. Se você combinar essa técnica para excluir primos grandes com uma peneira, terá um método de fatoração muito melhor do que apenas com a peneira.

E essa é apenas uma das muitas técnicas desenvolvidas. Este é bastante simples. Você levaria muito tempo para aprender, digamos, a teoria dos números suficiente para entender as técnicas de fatoração baseadas em curvas elípticas. (Eu sei que eles existem. Eu não os entendo.)

Portanto, a menos que você esteja lidando com números inteiros pequenos, eu não tentaria resolver esse problema sozinho. Em vez disso, tentaria encontrar uma maneira de usar algo como a biblioteca PARI que já possui uma solução altamente eficiente implementada. Com isso, eu posso fatorar um número aleatório de 40 dígitos como 124321342332143213122323434312213424231341 em cerca de 0,05 segundos. (Sua fatoração, no caso de você ter se perguntado, é 29 * 439 * 1321 * 157907 * 284749 * 33843676813 * 4857795469949. Estou bastante confiante de que não descobriu isso usando a peneira de Atkin ...)

user11318
fonte
1
Sua técnica é muito inteligente, mas não me diz quantos fatores esse número tem, pois não?
sker 21/09/08
23
Depois de ter a fatoração principal, descobrir quantos fatores existem é direto. Suponha que os fatores primos sejam p1, p2, ..., pk e eles sejam repetidos m1, m2, ..., mk vezes. Então existem fatores (1 + m1) (1 + m2) ... (1 + mk).
user11318
Uma peneira interessante é a peneira quadrática . Isso usa a teoria dos números - congruências quadráticas e alguma álgebra linear. Eu aprendi o suficiente para usá-lo em um curso de teoria dos números do segundo ano na universidade.
Tanner
33

@Yasky

Sua função de divisores possui um erro, pois não funciona corretamente para quadrados perfeitos.

Experimentar:

int divisors(int x) {
    int limit = x;
    int numberOfDivisors = 0;

    if (x == 1) return 1;

    for (int i = 1; i < limit; ++i) {
        if (x % i == 0) {
            limit = x / i;
            if (limit != i) {
                numberOfDivisors++;
            }
            numberOfDivisors++;
        }
    }

    return numberOfDivisors;
}
Kendall
fonte
6
(X% i) não causará uma divisão por zero quando i = 0? devo = 1..limitar?
21
@rhu Verificando 0 é inútil de qualquer maneira, porque 0 não é um fator de nenhum número.
EJoshuaS - Restabelece Monica
29

Discordo que a peneira de Atkin é o caminho a percorrer, porque poderia facilmente levar mais tempo para verificar todos os números em [1, n] quanto à primalidade do que reduzir o número por divisões.

Aqui está um código que, embora um pouco mais hackeado, geralmente é muito mais rápido:

import operator
# A slightly efficient superset of primes.
def PrimesPlus():
  yield 2
  yield 3
  i = 5
  while True:
    yield i
    if i % 6 == 1:
      i += 2
    i += 2
# Returns a dict d with n = product p ^ d[p]
def GetPrimeDecomp(n):
  d = {}
  primes = PrimesPlus()
  for p in primes:
    while n % p == 0:
      n /= p
      d[p] = d.setdefault(p, 0) + 1
    if n == 1:
      return d
def NumberOfDivisors(n):
  d = GetPrimeDecomp(n)
  powers_plus = map(lambda x: x+1, d.values())
  return reduce(operator.mul, powers_plus, 1)

ps Esse código de python está funcionando para resolver esse problema.

Tyler
fonte
11

Aqui está um algoritmo O (sqrt (n)) direto. Eu usei isso para resolver o projeto euler

def divisors(n):
    count = 2  # accounts for 'n' and '1'
    i = 2
    while i ** 2 < n:
        if n % i == 0:
            count += 2
        i += 1
    if i ** 2 == n:
        count += 1
    return count
Antony Thomas
fonte
mas por que você sempre aumenta a contagem em 2? ... existe um teorema que você aplicou?
SummerCode
3
porque você é contingente apenas até sqrt (n). Por exemplo: se você estiver tentando encontrar todos os divisores para 36 - contará de 2 a 6. Você sabe que 1 e 36,2 e 18, 3 e 12, 4 e 9, 6,6 são todos divisores e vêm em pares.
Antony Thomas
2
muito obrigado Anthony, eu entendi agora: D! um pequeno adendo: eu acho que deve tratar o valor sqrt (n) separadamente porque, por enquanto leva em consideração duas vezes em vez de um, eu acho
SummerCode
Embora O (sqrt (n)) não seja muito ruim, não é o ideal. calcular a decomposição do fator principal pode ser feito muito mais rapidamente e é suficiente para calcular o número de divisores.
22417 le_m
Em cada iteração, é necessário calcular i², não seria mais rápido comparar i com √n (calculado apenas uma vez)?
Yukulélé 13/04
10

Essa pergunta interessante é muito mais difícil do que parece e não foi respondida. A questão pode ser fatorada em duas questões muito diferentes.

1 dado N, encontre a lista L dos principais fatores de N

2 dado L, calcule o número de combinações únicas

Todas as respostas que vejo até agora se referem ao número 1 e não mencionam que não é tratável por números enormes. Para N de tamanho médio, até números de 64 bits, é fácil; para N enorme, o problema de fatoração pode demorar "para sempre". A criptografia de chave pública depende disso.

A pergunta 2 precisa de mais discussão. Se L contiver apenas números únicos, é um cálculo simples usando a fórmula de combinação para escolher k objetos de n itens. Na verdade, você precisa somar os resultados da aplicação da fórmula enquanto varia k de 1 a sizeof (L). No entanto, L normalmente conterá várias ocorrências de múltiplos números primos. Por exemplo, L = {2,2,2,3,3,5} é a fatoração de N = 360. Agora esse problema é bastante difícil!

Reajustando o item 2, dada a coleção C que contém itens k, de modo que o item a possui a 'duplicatas e o item b possui b' duplicatas, etc. Por exemplo, {2}, {2,2}, {2,2,2}, {2,3}, {2,2,3,3} devem ocorrer uma vez e apenas uma vez se L = {2,2 2,3,3,5}. Cada uma dessas sub-coleções exclusivas é um divisor exclusivo de N multiplicando os itens da sub-coleção.

dongilmore
fonte
Aqui está um link para algum código pseudo para um problema muito semelhante a 2. answers.google.com/answers/threadview/id/392914.html
mR_fr0g
3
A pergunta nº 2 tem uma solução conhecida. Para uma fatoração de {p_i, k_i} onde p_ié um fator primo de um número com k_imultiplicidade, o número total de divisores desse número é (k_1+1)*(k_2+1)*...*(k_n+1). Acho que você já sabe disso, mas escrevo isso para o benefício de um leitor aleatório aqui.
Will Ness
9

Uma resposta para sua pergunta depende muito do tamanho do número inteiro. Os métodos para números pequenos, por exemplo, menos de 100 bits e para números ~ 1000 bits (como os usados ​​em criptografia) são completamente diferentes.

jfs
fonte
6

APENAS uma linha
Pensei com muito cuidado na sua pergunta e tentei escrever um código altamente eficiente e com bom desempenho. Para imprimir todos os divisores de um determinado número na tela, precisamos de apenas uma linha de código! (use a opção -std = c99 durante a compilação via gcc)

for(int i=1,n=9;((!(n%i)) && printf("%d is a divisor of %d\n",i,n)) || i<=(n/2);i++);//n is your number

para encontrar números de divisores, você pode usar a seguinte função muito, muito rápida (funciona corretamente para todos os números inteiros, exceto 1 e 2)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    return counter;
}

ou se você tratar o número fornecido como um divisor (funcione corretamente para todo o número inteiro, exceto 1 e 2)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    return ++counter;
}

NOTA: as duas funções acima funcionam corretamente para todos os números inteiros positivos, exceto os números 1 e 2, portanto, são funcionais para todos os números maiores que 2, mas se você precisar cobrir 1 e 2, poderá usar uma das seguintes funções (um pouco Mais devagar)

int number_of_divisors(int n)
{
    int counter,i;
    for(counter=0,i=1;(!(n%i) && (counter++)) || i<=(n/2);i++);
    if (n==2 || n==1)
    {
    return counter;
    }
    return ++counter;
}

OU

int number_of_divisors(int n)
{
    int counter,i;
for(counter=0,i=1;(!(i==n) && !(n%i) && (counter++)) || i<=(n/2);i++);
    return ++counter;
}

Pequeno é bonito :)

هومن جاویدپور
fonte
5

A peneira de Atkin é uma versão otimizada da peneira de Eratóstenes, que fornece todos os números primos até um determinado número inteiro. Você deve pesquisar isso no Google para obter mais detalhes.

Depois de ter essa lista, é simples dividir seu número por cada primo para ver se é um divisor exato (ou seja, o restante é zero).

As etapas básicas do cálculo dos divisores para um número (n) são [este é um pseudocódigo convertido do código real, então espero não ter introduzido erros]:

for z in 1..n:
    prime[z] = false
prime[2] = true;
prime[3] = true;

for x in 1..sqrt(n):
    xx = x * x

    for y in 1..sqrt(n):
        yy = y * y

        z = 4*xx+yy
        if (z <= n) and ((z mod 12 == 1) or (z mod 12 == 5)):
            prime[z] = not prime[z]

        z = z-xx
        if (z <= n) and (z mod 12 == 7):
            prime[z] = not prime[z]

        z = z-yy-yy
        if (z <= n) and (x > y) and (z mod 12 == 11):
            prime[z] = not prime[z]

for z in 5..sqrt(n):
    if prime[z]:
        zz = z*z
        x = zz
        while x <= limit:
            prime[x] = false
            x = x + zz

for z in 2,3,5..n:
    if prime[z]:
        if n modulo z == 0 then print z
paxdiablo
fonte
5

Você pode tentar este. É um pouco tolo, mas é razoavelmente rápido.

def factors(n):
    for x in xrange(2,n):
        if n%x == 0:
            return (x,) + factors(n/x)
    return (n,1)
Michael
fonte
2
Enquanto esta função fornece um factor de decomposição principal de n em tempo razoável, isto é: a) não ser óptima e b) não se calcular o número de divisores de um determinado número, como por questão de OP
le_m
E não vai funcionar para números grandes por causa de sua recursão
whackamadoodle3000
Embora isso não seja o ideal e, em vez de contar os fatores, na verdade os lista , a simplicidade e a beleza disso são surpreendentes e razoavelmente rápidas. ^^
Gaurav Singhal
5

Depois de ter a fatoração principal, há uma maneira de encontrar o número de divisores. Adicione um a cada um dos expoentes em cada fator individual e multiplique os expoentes juntos.

Por exemplo: 36 Fatoração primária: 2 ^ 2 * 3 ^ 2 Divisores: 1, 2, 3, 4, 6, 9, 12, 18, 36 Número de divisores: 9

Adicione um a cada expoente 2 ^ 3 * 3 ^ 3 Multiplique expoentes: 3 * 3 = 9

D. Williams
fonte
3

Antes de se comprometer com uma solução, considere que a abordagem da peneira pode não ser uma boa resposta no caso típico.

Um tempo atrás, havia uma pergunta principal e eu fiz um teste de tempo - para números inteiros de 32 bits, pelo menos, determinar se era primo era mais lento que a força bruta. Existem dois fatores:

1) Enquanto um humano leva um tempo para fazer uma divisão, ele é muito rápido no computador - semelhante ao custo de procurar a resposta.

2) Se você não possui uma tabela principal, pode fazer um loop que é executado inteiramente no cache L1. Isso torna mais rápido.

Loren Pechtel
fonte
3

Esta é uma solução eficiente:

#include <iostream>
int main() {
  int num = 20; 
  int numberOfDivisors = 1;

  for (int i = 2; i <= num; i++)
  {
    int exponent = 0;
    while (num % i == 0) {
        exponent++; 
        num /= i;
    }   
    numberOfDivisors *= (exponent+1);
  }

  std::cout << numberOfDivisors << std::endl;
  return 0;
}
Эсмер Амрахлы
fonte
2

Os divisores fazem algo espetacular: eles se dividem completamente. Se você deseja verificar o número de divisores para um número n, é claramente redundante abranger todo o espectro 1...n,. Não fiz nenhuma pesquisa aprofundada para isso, mas resolvi o problema do Projeto Euler 12 em Números Triangulares . Minha solução para o teste de mais de 500 divisores foi executada por 309504 microssegundos (~ 0,3s). Eu escrevi essa função divisora ​​para a solução.

int divisors (int x) {
    int limit = x;
    int numberOfDivisors = 1;

    for (int i(0); i < limit; ++i) {
        if (x % i == 0) {
            limit = x / i;
            numberOfDivisors++;
        }
    }

    return numberOfDivisors * 2;
}

Para todo algoritmo, há um ponto fraco. Eu pensei que isso era fraco contra números primos. Mas, como os números triangulares não são impressos, ele serviu a seu propósito na perfeição. Pelo meu perfil, acho que foi muito bem.

Boas festas.

iGbanam
fonte
1
Você teria uma divisão por 0 na primeira iteração aqui
barfoon
Infelizmente não. a ++ i é diferente de i ++ (o que resultaria em um erro de divisão por zero)
iGbanam
Eu escrevi a função em PHP e ele correu - aqui está o que eu tenho - i.minus.com/iKzuSXesAkpbp.png
barfoon
por algum motivo estranho, isso funcionou perfeitamente para mim. oh bem, meu mal. start numberOfDivisorse o iterador em 1; isso deve se livrar do erro de divisão por zero
iGbanam 21/10
1
Seu algoritmo não funciona para quadrados perfeitos. Por exemplo, ele retorna 4 para a entrada x = 4, porque está contando 2 duas vezes ... 1, 2, 2, 4. A resposta deve ser 3: 1,2,4
Michael
1

Você deseja a peneira de Atkin, descrita aqui: http://en.wikipedia.org/wiki/Sieve_of_Atkin

SquareCog
fonte
1
Isso fornecerá os números primos abaixo do número especificado - mas não há garantia de que esses números sejam divisores? (a menos que eu estou faltando alguma coisa)
Andrew Edgecombe
É um salto rápido a partir de aqui para encontrar todos os números primos <sqrt (N) que dividir igualmente N.
SquareCog
1
Pode ser um salto rápido, mas testar todos os números primos <sqrt (N) ainda é uma técnica de fatoração ruim, independentemente da eficiência com que você os encontra. Existem várias maneiras de melhorar isso.
user11318
Testar os primos é O (N), é encontrar os primos, que é a parte mais difícil. Mas mesmo com a peneira não otimizada de eratóstenes, você ainda pode encontrar todos os números primos abaixo de alguns milhões em menos de um segundo. Isso abrange qualquer número 64b, e tenho certeza de que não estamos falando sobre fatorar coisas de nível de criptografia aqui
Matthew Scharley
1

o método dos números primos é muito claro aqui. P [] é uma lista de números primos menor ou igual a sq = sqrt (n);

for (int i = 0 ; i < size && P[i]<=sq ; i++){
          nd = 1;
          while(n%P[i]==0){
               n/=P[i];
               nd++;
               }
          count*=nd;
          if (n==1)break;
          }
      if (n!=1)count*=2;//the confusing line :D :P .

     i will lift the understanding for the reader  .
     i now look forward to a method more optimized  .
abdelkarim
fonte
1

Os livros de teoria dos números chamam a função de contagem de divisores tau. O primeiro fato interessante é que é multiplicativo, ie. τ (ab) = τ (a) τ (b), quando aeb não têm fator comum. (Prova: cada par de divisores de aeb fornece um divisor distinto de ab).

Agora observe que para pa prim, τ (p ** k) = k + 1 (os poderes de p). Assim, você pode calcular facilmente τ (n) a partir de sua fatoração.

No entanto, a fatoração de grandes números pode ser lenta (a segurança da critografia RSA depende do produto de dois primos grandes ser difícil de fatorar). Isso sugere esse algoritmo otimizado

  1. Teste se o número é primo (rápido)
  2. Em caso afirmativo, retorne 2
  3. Caso contrário, fatore o número (lento se vários fatores primos grandes)
  4. Calcular τ (n) a partir da fatoração
Coronel Panic
fonte
1

A seguir, é apresentado um programa em C para encontrar o número de divisores de um determinado número.

A complexidade do algoritmo acima é O (sqrt (n)).

Esse algoritmo funcionará corretamente para o número que é o quadrado perfeito, bem como os números que não são o quadrado perfeito.

Observe que o limite superior do loop é definido como a raiz quadrada do número para que o algoritmo seja mais eficiente.

Observe que armazenar o limite superior em uma variável separada também economiza tempo, você não deve chamar a função sqrt na seção de condição do loop for, isso também economiza seu tempo computacional.

#include<stdio.h>
#include<math.h>
int main()
{
    int i,n,limit,numberOfDivisors=1;
    printf("Enter the number : ");
    scanf("%d",&n);
    limit=(int)sqrt((double)n);
    for(i=2;i<=limit;i++)
        if(n%i==0)
        {
            if(i!=n/i)
                numberOfDivisors+=2;
            else
                numberOfDivisors++;
        }
    printf("%d\n",numberOfDivisors);
    return 0;
}

Em vez do loop for acima, você também pode usar o seguinte loop, que é ainda mais eficiente, pois elimina a necessidade de encontrar a raiz quadrada do número.

for(i=2;i*i<=n;i++)
{
    ...
}
Lavish Kothari
fonte
1

Aqui está uma função que eu escrevi. é a pior complexidade de tempo é O (sqrt (n)), por outro lado, é melhor (O (log (n))). Ele fornece todos os principais divisores, juntamente com o número de ocorrências.

public static List<Integer> divisors(n) {   
    ArrayList<Integer> aList = new ArrayList();
    int top_count = (int) Math.round(Math.sqrt(n));
    int new_n = n;

    for (int i = 2; i <= top_count; i++) {
        if (new_n == (new_n / i) * i) {
            aList.add(i);
            new_n = new_n / i;
            top_count = (int) Math.round(Math.sqrt(new_n));
            i = 1;
        }
    }
    aList.add(new_n);
    return aList;
}
Adilli Adil
fonte
Não sei o que essa função calcula, mas definitivamente não é a lista de divisores de n.
le_m
1

Esta é a maneira mais básica de calcular o número de tesouras:

class PrintDivisors
{
    public static void main(String args[])
    {

    System.out.println("Enter the number");

    // Create Scanner object for taking input
    Scanner s=new Scanner(System.in);

    // Read an int
    int n=s.nextInt();

        // Loop from 1 to 'n'
        for(int i=1;i<=n;i++)
        {

            // If remainder is 0 when 'n' is divided by 'i',
            if(n%i==0)
            {
            System.out.print(i+", ");
            }
        }

    // Print [not necessary]    
    System.out.print("are divisors of "+n);

    }
}
Malik
fonte
1

@Kendall

Testei seu código e fiz algumas melhorias, agora é ainda mais rápido. Também testei com o código @ هومن جاویدپور, que também é mais rápido que o código dele.

long long int FindDivisors(long long int n) {
  long long int count = 0;
  long long int i, m = (long long int)sqrt(n);
  for(i = 1;i <= m;i++) {
    if(n % i == 0)
      count += 2;
  }
  if(n / m == m && n % m == 0)
    count--;
  return count;
}
as2d3
fonte
0

Não é apenas uma questão de fatorar o número - determinar todos os fatores do número? Você pode decidir se precisa de todas as combinações de um ou mais fatores.

Portanto, um algoritmo possível seria:

factor(N)
    divisor = first_prime
    list_of_factors = { 1 }
    while (N > 1)
        while (N % divisor == 0)
            add divisor to list_of_factors
            N /= divisor
        divisor = next_prime
    return list_of_factors

Cabe a você combinar os fatores para determinar o restante da resposta.

Jonathan Leffler
fonte
0

Isso é algo que eu criei com base na resposta do Justin. Pode exigir alguma otimização.

n=int(input())

a=[]
b=[]

def sieve(n):
    np = n + 1
    s = list(range(np)) 
    s[1] = 0
    sqrtn = int(n**0.5)
    for i in range(2, sqrtn + 1): 
        if s[i]:
            s[i*i: np: i] = [0] * len(range(i*i, np, i))
    return filter(None, s)

k=list(sieve(n))

for i in range(len(k)):
        if n%k[i]==0:
                a.append(k[i])

a.sort()

for i in range(len(a)):
        j=1
        while n%(a[i]**j)==0: 
                j=j+1
        b.append(j-1)

nod=1

for i in range(len(b)):
        nod=nod*(b[i]+1)

print('no.of divisors of {} = {}'.format(n,nod))
winsid96
fonte
0

Acho que é isso que você está procurando. Faz exatamente o que você pediu. Se você deseja obter mais informações sobre o produto, por favor, contate nosso departamento de vendas ou solicite um orçamento.

Observe que uma variável CMD não pode suportar valores acima de 999999999

@echo off

modecon:cols=100 lines=100

:start
title Enter the Number to Determine 
cls
echo Determine a number as a product of 2 numbers
echo.
echo Ex1 : C = A * B
echo Ex2 : 8 = 4 * 2
echo.
echo Max Number length is 9
echo.
echo If there is only 1 proces done  it
echo means the number is a prime number
echo.
echo Prime numbers take time to determine
echo Number not prime are determined fast
echo.

set /p number=Enter Number : 
if %number% GTR 999999999 goto start

echo.
set proces=0
set mindet=0
set procent=0
set B=%Number%

:Determining

set /a mindet=%mindet%+1

if %mindet% GTR %B% goto Results

set /a solution=%number% %%% %mindet%

if %solution% NEQ 0 goto Determining
if %solution% EQU 0 set /a proces=%proces%+1

set /a B=%number% / %mindet%

set /a procent=%mindet%*100/%B%

if %procent% EQU 100 set procent=%procent:~0,3%
if %procent% LSS 100 set procent=%procent:~0,2%
if %procent% LSS 10 set procent=%procent:~0,1%

title Progress : %procent% %%%



if %solution% EQU 0 echo %proces%. %mindet% * %B% = %number%
goto Determining

:Results

title %proces% Results Found
echo.
@pause
goto start
dondon
fonte
882161280 - 1282 divisores
dondon
0

Eu acho que este será útil e preciso

script.pyton

>>>factors=[ x for x in range (1,n+1) if n%x==0] print len(factors)

Syed Hissaan
fonte
0

Tente algo como estas:

int divisors(int myNum) {
    int limit = myNum;
    int divisorCount = 0;
    if (x == 1) 
        return 1;
    for (int i = 1; i < limit; ++i) {
        if (myNum % i == 0) {
            limit = myNum / i;
            if (limit != i)
                divisorCount++;
            divisorCount++;
        }
    }
    return divisorCount;
}
Bryant Jackson
fonte
-1

Não conheço o método MAIS eficiente, mas faria o seguinte:

  • Crie uma tabela de números primos para encontrar todos os números primos menores ou iguais à raiz quadrada do número (pessoalmente, eu usaria a peneira de Atkin)
  • Conte todos os números primos menores ou iguais à raiz quadrada do número e multiplique por dois. Se a raiz quadrada do número for um número inteiro, subtraia um da variável count.

Deve funcionar \ o /

Se você precisar, eu posso codificar algo amanhã em C para demonstrar.

Ponto e vírgula
fonte
2
Estou confuso. Contar todos os números primos menores que a raiz quadrada de um número não fornecerá seus divisores ... nem todo primo menor que a raiz quadrada de um número será um divisor para esse número.
Garrett Berg