2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								id: 598eea87e5cf4b116c3ff81a
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								title: Factors of a Mersenne number
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								challengeType: 5
							 
						 
					
						
							
								
									
										
										
										
											2019-08-05 09:17:33 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								forumTopicId: 302264
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 03:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								dashedName: factors-of-a-mersenne-number
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# --description--
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								A Mersenne number is a number in the form of < code > 2< sup > P< / sup > -1< / code > .
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								If `P`  is prime, the Mersenne number may be a Mersenne prime. (If `P`  is not prime, the Mersenne number is also not prime.)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								In the search for Mersenne prime numbers it is advantageous to eliminate exponents by finding a small factor before starting a, potentially lengthy, [Lucas-Lehmer test ](<https://rosettacode.org/wiki/Lucas-Lehmer test> "Lucas-Lehmer test" ).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								There are very efficient algorithms for determining if a number divides < code > 2< sup > P< / sup > -1< / code >  (or equivalently, if < code > 2< sup > P< / sup >  mod (the number) = 1< / code > ).
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 21:27:55 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Some languages already have built-in implementations of this exponent-and-mod operation (called modPow or similar).
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 21:27:55 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								The following is how to implement this modPow yourself:
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								For example, let's compute < code > 2< sup > 23< / sup >  mod 47< / code > .
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Convert the exponent 23 to binary, you get 10111. Starting with < code > < tt > square< / tt >  = 1< / code > , repeatedly square it.
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Remove the top bit of the exponent, and if it's 1 multiply `square`  by the base of the exponentiation (2), then compute < code >< tt > square</ tt >  modulo 47</ code > .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Use the result of the modulo from the last step as the initial value of `square`  in the next step:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								< pre > Remove   Optional
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 21:27:55 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								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 > 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Since < code > 2< sup > 23< / sup >  mod 47 = 1< / code > , 47 is a factor of < code > 2< sup > P< / sup > -1< / code > .
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								(To see this, subtract 1 from both sides: < code > 2< sup > 23< / sup > -1 = 0 mod 47< / code > .)
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-14 20:04:16 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Since we've shown that 47 is a factor, < code > 2< sup > 23< / sup > -1< / code >  is not prime.
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 21:27:55 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Further properties of Mersenne numbers allow us to refine the process even more.
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Any factor `q`  of < code > 2< sup > P</ sup > -1</ code >  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 ](<https://rosettacode.org/wiki/Primality by Trial Division> "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, < code > M< sub > 4</ sub > =15</ code >  yields no factors using these techniques, but factors into 3 and 5, neither of which fit `2kP+1` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# --instructions--
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 07:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Using the above method find a factor of < code > 2< sup > p< / sup > -1< / code > .
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# --hints--
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								`check_mersenne`  should be a function.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								assert(typeof check_mersenne === 'function');
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								`check_mersenne(3)`  should return a string.
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								assert(typeof check_mersenne(3) == 'string');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 07:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								`check_mersenne(3)`  should return the string `M3 = 2^3-1 is prime` .
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2020-09-15 09:57:40 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 07:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								`check_mersenne(23)`  should return the string `M23 = 2^23-1 is composite with factor 47` .
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								assert.equal(check_mersenne(23), 'M23 = 2^23-1 is composite with factor 47');
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 07:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								`check_mersenne(929)`  should return the string `M929 = 2^929-1 is composite with factor 13007` .
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								assert.equal(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  check_mersenne(929),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  'M929 = 2^929-1 is composite with factor 13007'
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# --seed--
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								## --seed-contents--
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function check_mersenne(p) {
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# --solutions--
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2018-10-08 01:01:53 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function check_mersenne(p){
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    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;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }
							 
						 
					
						
							
								
									
										
										
										
											2018-09-30 23:01:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  let f, result;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result="M"+p+" = 2^"+p+"-1 is ";
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  f = mersenne_factor(p);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result+=f == null ? "prime" : "composite with factor "+f;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return result;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								```