--- id: 598eea87e5cf4b116c3ff81a title: Fatores de um número de Mersenne challengeType: 5 forumTopicId: 302264 dashedName: factors-of-a-mersenne-number --- # --description-- Um número de Mersenne é um número na forma de 2P-1. Se `P` for primo, o número de Mersenne pode ser primo de Mersenne. (Se `P` não for primo, o número de Mersenne também não será primo.) Na busca por números primos de Mersenne, é vantajoso eliminar expoentes, encontrando um pequeno fator antes de iniciar um [teste de Lucas-Lehmer](https://rosettacode.org/wiki/Lucas-Lehmer test "Lucas-Lehmer test"), potencialmente extenso. Existem algoritmos muito eficientes para determinar se um número divide 2P-1 (ou, de modo equivalente, se 2P mod (o número) = 1). Algumas linguagens já possuem implementações integradas desta operação exponente-e-mod (chamada modPow ou algo similar). A seguir, vemos como você mesmo pode implementar este modPow: Por exemplo, vamos calcular 223 mod 47. Converta o expoente 23 em binário, você obtém 10111. Começando com square = 1, eleve-o repetidamente ao quadrado. Remova a parte superior do expoente e, se for 1, multiplique `square` pela base da exponenciação (2). Então, calcule square modulo 47. Use o resultado do módulo da última etapa como o valor inicial de `square` na próxima etapa:
Remova   Opcional
square        pte sup  multiplique 2  mod 47
------------  -------  -------------  ------
1*1 = 1       1  0111  1*2 = 2           2
2*2 = 4       0   111     no             4
4*4 = 16      1    11  16*2 = 32        32
32*32 = 1024  1     1  1024*2 = 2048    27
27*27 = 729   1        729*2 = 1458      1
Como 223 mod 47 = 1, 47 é um fator de 2P-1. (Para ver isso, subtraia 1 de ambos os lados: 223-1 = 0 mod 47.) Como mostramos que 47 é um fator, 223-1 não é primo. Outras propriedades dos números de Mersenne nos permitem refinar ainda mais o processo. Qualquer fator `q` de 2P-1 deve ser no formato `2kP+1`, `k`, sendo um inteiro positivo ou zero. Além disso, `q` deve ser `1` ou `7 mod 8`. Por fim, qualquer fator potencial `q` deve ser [primo](https://rosettacode.org/wiki/Primality by Trial Division "Primality by Trial Division"). Como em outros algoritmos de divisão de teste, o algoritmo termina quando `2kP+1 > sqrt(N)`. Estes testes só funcionam em números de Mersenne, onde o `P` é primo. Por exemplo, M4=15 não gera fatores usando essas técnicas, mas fator em 3 e 5, nenhum dos quais se ajusta a `2kP+1`. # --instructions-- Usando o método acima, encontre um fator de 2p-1. # --hints-- `check_mersenne` deve ser uma função. ```js assert(typeof check_mersenne === 'function'); ``` `check_mersenne(3)` deve retornar uma string. ```js assert(typeof check_mersenne(3) == 'string'); ``` `check_mersenne(3)` deve retornar a string `M3 = 2^3-1 is prime`. ```js assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime'); ``` `check_mersenne(23)` deve retornar a string `M23 = 2^23-1 is composite with factor 47`. ```js assert.equal(check_mersenne(23), 'M23 = 2^23-1 is composite with factor 47'); ``` `check_mersenne(929)` deve retornar a string `M929 = 2^929-1 is composite with factor 13007`. ```js assert.equal( check_mersenne(929), 'M929 = 2^929-1 is composite with factor 13007' ); ``` # --seed-- ## --seed-contents-- ```js function check_mersenne(p) { } ``` # --solutions-- ```js function check_mersenne(p){ function isPrime(value){ for (let i=2; i < value; i++){ if (value % i == 0){ return false; } if (value % i != 0){ return true; } } } function trial_factor(base, exp, mod){ let square, bits; square = 1; bits = exp.toString(2).split(''); for (let i=0,ln=bits.length; i