--- id: 598eea87e5cf4b116c3ff81a title: I fattori di un numero di Mersenne challengeType: 5 forumTopicId: 302264 dashedName: factors-of-a-mersenne-number --- # --description-- Un numero di Mersenne è un numero nella forma di 2P-1. Se `P` è primo, il numero di Mersenne può essere un primo di Mersenne. (Se `P` non è primo, anche il numero di Mersenne non è primo.) 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"). Ci sono algoritmi molto efficienti per determinare se un numero divide 2P-1 (o equivalentemente, se 2P mod (il numero) = 1). Alcuni linguaggi hanno già implementazioni integrate di questa operazione esponente-e-modulo (chiamata modPow o simile). Ecco come puoi implementare questo modPow: Ad esempio, calcoliamo 223 mod 47. Converti l'esponente 23 in binario, ottenendo 10111. A partire da square = 1, fai ripetutamente il quadrato. Rimuovi il bit superiore dell'esponente, e se è 1 moltiplica `square` per la base dell'esponenziazione (2), poi calcola square modulo 47. Usa il risultato del modulo dall'ultimo passo come valore iniziale dello `square` nella fase successiva:
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
Dal momento che 223 mod 47 = 1, 47 è un fattore di 2P-1. (Per vedere questo, sottrai 1 da entrambi i lati: 223-1 = 0 mod 47.) Dal momento che abbiamo dimostrato che 47 è un fattore, 223-1 non è primo. Ulteriori proprietà dei numeri di Mersenne ci permettono di affinare il processo ancora di più. Qualsiasi fattore `q` di 2P-1 deve essere modulo `2kP+1`, essendo `k` un numero intero positivo o uguale a zero. Inoltre, `q` deve essere `1` o `7 mod 8`. Infine qualsiasi fattore potenziale `q` deve essere [primo](https://rosettacode.org/wiki/Primality by Trial Division "Primality by Trial Division"). 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, M4=15 non produce fattori che utilizzano queste tecniche, ma fattori in 3 e 5, nessuno dei quali nella forma `2kP+1`. # --instructions-- Utilizzando il metodo sopra descritto trovare un fattore di 2p-1. # --hints-- `check_mersenne` dovrebbe essere una funzione. ```js assert(typeof check_mersenne === 'function'); ``` `check_mersenne(3)` dovrebbe restituire una stringa. ```js assert(typeof check_mersenne(3) == 'string'); ``` `check_mersenne(3)` dovrebbe restituire la stringa `M3 = 2^3-1 is prime`. ```js assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime'); ``` `check_mersenne(23)` dovrebbe restituire la stringa `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)` dovrebbe restituire la stringa `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