"Lucas-Lehmer test").
There are very efficient algorithms for determining if a number divides 2P-1
(or equivalently, if 2P mod (the number) = 1
).
Some languages already have built-in implementations of this exponent-and-mod operation (called modPow or similar).
The following is how to implement this modPow yourself:
For example, let's compute 223 mod 47
.
Convert the exponent 23 to binary, you get 10111. Starting with square = 1
, repeatedly square it.
Remove the top bit of the exponent, and if it's 1 multiply `square` by the base of the exponentiation (2), then compute square modulo 47
.
Use the result of the modulo from the last step as the initial value of `square` in the next step:
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
Since 223 mod 47 = 1
, 47 is a factor of 2P-1
.
(To see this, subtract 1 from both sides: 223-1 = 0 mod 47
.)
Since we've shown that 47 is a factor, 223-1
is not prime.
Further properties of Mersenne numbers allow us to refine the process even more.
Any factor `q` of 2P-1
must be of the form `2kP+1`, `k` being a positive integer or zero. Furthermore, `q` must be `1` or `7 mod 8`.
Finally any potential factor `q` must be [prime]( "Primality by Trial Division").
As in other trial division algorithms, the algorithm stops when `2kP+1 > sqrt(N)`.These primarily tests only work on Mersenne numbers where `P` is prime. For example, M4=15
yields no factors using these techniques, but factors into 3 and 5, neither of which fit `2kP+1`.
# --instructions--
Using the above method find a factor of 2p-1
.
# --hints--
`check_mersenne` should be a function.
```js
assert(typeof check_mersenne === 'function');
```
`check_mersenne(3)` should return a string.
```js
assert(typeof check_mersenne(3) == 'string');
```
`check_mersenne(3)` should return the string `M3 = 2^3-1 is prime`.
```js
assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime');
```
`check_mersenne(23)` should return the 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)` should return the 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