Este exemplo em Rust guarda os primos encontrados e os usa na divisão por tentativa. primes_up_to(max) retorna uma lista de primos até o limite, inclusive. Existem 168 primos menores ou iguais a 1000; 0 e 1 não são primos. Não é uma implementação de crivo.
Código
| |
Execução e limites pequenos
Salve como primes.rs e compile com rustc --edition=2021 primes.rs -o primes. No Windows, use primes.exe como nome do executável. A execução imprime 168 linhas, começando por 2 e terminando em 997. Estes exemplos foram executados com Rust 1.90.0.
primes_up_to(0) e primes_up_to(1) retornam um vetor vazio; primes_up_to(2) retorna [2], primes_up_to(3) retorna [2, 3], e primes_up_to(10) retorna [2, 3, 5, 7]. O tipo do parâmetro, usize, exclui limites negativos. Este programa não analisa a entrada padrão.
Como funcionam o teste e o laço
- Retorne um resultado vazio para um limite menor que 2. Caso contrário, guarde 2 e teste apenas os candidatos ímpares de 3 até o limite. O limite é verificado antes de processar cada candidato, portanto o limite 2 não adiciona 3.
- Um candidato composto
ntem um fator primo menor ou igual à sua raiz quadrada. Esses primos já estão na lista a partir dos candidatos anteriores. Se uma divisão não deixar resto, rejeite o candidato. Se nenhum divisor foi encontrado quandop > n / p, não é necessário continuar a divisão por tentativa. A divisão inteira positiva expressa a condição da raiz quadrada sem calcularp * pnem uma raiz em ponto flutuante. for &p in &primestoma a lista emprestada, recebe referências sucessivas e copia cada valorusizeparap. Um primo novo só é adicionado depois que esse laço termina. Ofor p in primes_up_to(1000)final retira os valores do vetor retornado e os imprime. A documentação de Vec do Rust distingue a iteração por empréstimo da iteração que assume a propriedade do vetor e o consome.- Dentro de
n <= max,max - nnão pode ser negativo. Se a distância restante for menor que 2, saia antes de somar; caso contrário, executen += 2. Assim, o incremento não ultrapassa o limite.
Aplicabilidade
O programa original com limite fixo 1000 também imprime corretamente 168 primos. Porém, trocar apenas o limite para 0, 1 ou 2 produz valores 2 ou 3 fora do intervalo, pois o limite não é verificado antes do processamento. A função reutilizável aqui trata essas fronteiras.
A lista guarda um usize por primo descoberto. Os metadados do vetor e a capacidade alocada também precisam de memória. Um limite superior aproximado para as divisões é O(max sqrt(max)), contando uma divisão como uma operação; não é tempo medido nem complexidade em bits. Limites maiores exigem mais tempo e armazenamento, sem garantia de listar rapidamente primos até limites arbitrariamente grandes. Para intervalos grandes, veja o artigo sobre o crivo de Eratóstenes. Não é um gerador de primos criptográficos.
