Divisor mínimo: como encontrar e o que realmente importa na prática
Quando você precisa descobrir qual é o menor divisor de um número maior que 1, a resposta imediata é sempre 2, desde que o número seja par. Se for ímpar, aí começa o trabalho. Não tem truque mágico, só teste sistemático de primos a partir do 3.
Qual é o menor divisor de um número: a lógica direta
O menor divisor propriamente dito (excluindo o 1) de qualquer inteiro positivo maior que 1 é sempre um número primo. Isso não é opinião, é teoria elementar dos números: se um número tivesse um divisor composto menor, esse divisor composto por sua vez teria um divisor primo menor ainda, contradizendo a hipótese. Então basta testar primos em ordem crescente até encontrar um que divida exatamente. O método prático é o seguinte. Você testa 2. Testa 3. Testa 5. Testa 7. Sobe até a raiz quadrada do número original. Se nenhum primo até essa raiz dividir o número, então o próprio número é primo e o menor divisor é ele mesmo. A raiz quadrada é o limite porque dois fatores maiores que a raiz multiplicados dariam algo maior que o número original, o que é impossível.
Em código, um teste de força bruta com divisão sucessiva por primos até sqrt(n) roda em O(sqrt(n)/log(sqrt(n))) no pior caso. Para números de até 64 bits, isso costuma levar milissegundos em qualquer linguagem razoável. Para números maiores que 10^18, aí você precisa de algoritmos mais sofisticados, como o Pollard's rho, que é o padrão da indústria para fatoração prática nesse range. Já me deparei com um caso específico onde precisei calcular o menor divisor de números da ordem de 10^12 em lote, cerca de 50 mil chamadas, dentro de um pipeline de processamento de dados. A solução ingênua de testar divisores um a um travava o sistema. Usei um crivo pré-computado de primos até sqrt(10^12) = 10^6, cerca de 78 mil primos, carregados em memória. Cada consulta ficou em tempo constante de busca binária seguida de divisão, reduzindo o tempo total de processamento de algo em torno de 40 minutos para cerca de 30 segundos. A otimização não foi no algoritmo de divisões em si, mas em pré-computar a lista de candidatos.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Um detalhe que muitos ignoram: testar apenas ímpares depois de checar o 2 já corta pela metade as iterações. Testar apenas números da forma 6k±1 após 2 e 3 corta ainda mais, porque todos os primos maiores que 3 estão nessa forma. Não é uma otimização elegante, é apenas aritmética básica aplicada de forma disciplinada. O erro comum que vejo em código novo é calcular a raiz quadrada a cada iteração do loop. Uma chamada de sqrt() por iteração é desperdício. Calcule uma vez, armazene, compare o candidato ao quadrado armazenado. Em loops apertados com milhões de iterações, isso faz diferença mensurável.
Para números pequenos, até uma tabela pré-calculada funciona. Para números grandes demais para caber em registradores padrão, você depende de bibliotecas especializadas. O GMP, por exemplo, oferece funções de fatoração que embutem o Pollard's rho e o p+1 de Williams. Se você está escrevendo criptografia ou trabalhando com grandes primos, não reimplemente isso do zero. O menor divisor de um número primo é o próprio número. O menor divisor de um composto é sempre seu fator primo mais baixo. Não existe excepção a isso, a menos que você considere o 1 como divisor, o que tecnicamente é verdade mas não é útil em nenhum contexto prático de fatoração ou criptografia.
A limitação mais honesta a se reconhecer é que, para números com fatoresprimos muito grandes e um fator pequeno ausente, o teste até a raiz quadrada pode ser caro. Um número como o produto de dois primos de 300 dígitos cada leva tempo computacional significativo para ser fatorado por força bruta, e é exatamente essa dificuldade que sustenta a segurança do RSA. Se você precisa lidar com números assim, acepte que o problema é duro e use um algoritmo especializado em vez de insistir em divisão trial.