2021-06-15 00:49:18 -07:00
---
id: 598eea87e5cf4b116c3ff81a
2022-02-16 22:48:09 +05:30
title: I fattori di un numero di Mersenne
2021-06-15 00:49:18 -07:00
challengeType: 5
forumTopicId: 302264
dashedName: factors-of-a-mersenne-number
---
# --description--
2022-02-16 22:48:09 +05:30
Un numero di Mersenne è un numero nella forma di < code > 2< sup > P< / sup > -1< / code > .
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Se `P` è primo, il numero di Mersenne può essere un primo di Mersenne. (Se `P` non è primo, anche il numero di Mersenne non è primo.)
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Nella ricerca di numeri primari di Mersenne è vantaggioso eliminare gli esponenti trovando un piccolo fattore prima di iniziare un potenzialmente lungo [test di Lucas-Lehmer ](https://rosettacode.org/wiki/Lucas-Lehmer test "Lucas-Lehmer test" ).
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Ci sono algoritmi molto efficienti per determinare se un numero divide < code > 2< sup > P< / sup > -1< / code > (o equivalentemente, se < code > 2< sup > P< / sup > mod (il numero) = 1< / code > ).
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Alcuni linguaggi hanno già implementazioni integrate di questa operazione esponente-e-modulo (chiamata modPow o simile).
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Ecco come puoi implementare questo modPow:
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Ad esempio, calcoliamo < code > 2< sup > 23< / sup > mod 47< / code > .
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Converti l'esponente 23 in binario, ottenendo 10111. A partire da < code > < tt > square< / tt > = 1< / code > , fai ripetutamente il quadrato.
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Rimuovi il bit superiore dell'esponente, e se è 1 moltiplica `square` per la base dell'esponenziazione (2), poi calcola < code >< tt > square</ tt > modulo 47</ code > .
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Usa il risultato del modulo dall'ultimo passo come valore iniziale dello `square` nella fase successiva:
2021-06-15 00:49:18 -07:00
< pre > Remove Optional
square top bit multiply by 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
< / pre >
2022-02-16 22:48:09 +05:30
Dal momento che < code > 2< sup > 23< / sup > mod 47 = 1< / code > , 47 è un fattore di < code > 2< sup > P< / sup > -1< / code > .
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
(Per vedere questo, sottrai 1 da entrambi i lati: < code > 2< sup > 23< / sup > -1 = 0 mod 47< / code > .)
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Dal momento che abbiamo dimostrato che 47 è un fattore, < code > 2< sup > 23< / sup > -1< / code > non è primo.
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Ulteriori proprietà dei numeri di Mersenne ci permettono di affinare il processo ancora di più.
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Qualsiasi fattore `q` di < code > 2< sup > P</ sup > -1</ code > deve essere modulo `2kP+1` , essendo `k` un numero intero positivo o uguale a zero. Inoltre, `q` deve essere `1` o `7 mod 8` .
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Infine qualsiasi fattore potenziale `q` deve essere [primo ](https://rosettacode.org/wiki/Primality by Trial Division "Primality by Trial Division" ).
2021-06-15 00:49:18 -07:00
2022-02-16 22:48:09 +05:30
Come in altri algoritmi di divisione di prova, l'algoritmo si ferma quando `2kP+1 > sqrt(N)` . Questi test funzionano principalmente solo su numeri Mersenne dove `P` è primo. Ad esempio, < code > M< sub > 4</ sub > =15</ code > non produce fattori che utilizzano queste tecniche, ma fattori in 3 e 5, nessuno dei quali nella forma `2kP+1` .
2021-06-15 00:49:18 -07:00
# --instructions--
2022-02-16 22:48:09 +05:30
Utilizzando il metodo sopra descritto trovare un fattore di < code > 2< sup > p< / sup > -1< / code > .
2021-06-15 00:49:18 -07:00
# --hints--
2022-02-16 22:48:09 +05:30
`check_mersenne` dovrebbe essere una funzione.
2021-06-15 00:49:18 -07:00
```js
assert(typeof check_mersenne === 'function');
```
2022-02-16 22:48:09 +05:30
`check_mersenne(3)` dovrebbe restituire una stringa.
2021-06-15 00:49:18 -07:00
```js
assert(typeof check_mersenne(3) == 'string');
```
2022-02-16 22:48:09 +05:30
`check_mersenne(3)` dovrebbe restituire la stringa `M3 = 2^3-1 is prime` .
2021-06-15 00:49:18 -07:00
```js
assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime');
```
2022-02-16 22:48:09 +05:30
`check_mersenne(23)` dovrebbe restituire la stringa `M23 = 2^23-1 is composite with factor 47` .
2021-06-15 00:49:18 -07:00
```js
assert.equal(check_mersenne(23), 'M23 = 2^23-1 is composite with factor 47');
```
2022-02-16 22:48:09 +05:30
`check_mersenne(929)` dovrebbe restituire la stringa `M929 = 2^929-1 is composite with factor 13007` .
2021-06-15 00:49:18 -07:00
```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< ln ; i + + ) {
square = Math.pow(square, 2) * (bits[i] == 1 ? base : 1) % mod;
}
return (square == 1);
}
function mersenne_factor(p){
let limit, k, q;
limit = Math.sqrt(Math.pow(2,p) - 1);
k = 1;
while ((2*k*p - 1) < limit ) {
q = 2*k*p + 1;
if (isPrime(q) & & (q % 8 == 1 || q % 8 == 7) & & trial_factor(2,p,q)){
return q; // q is a factor of 2**p-1
}
k++;
}
return null;
}
let f, result;
result="M"+p+" = 2^"+p+"-1 is ";
f = mersenne_factor(p);
result+=f == null ? "prime" : "composite with factor "+f;
return result;
}
```