A Mersenne Prime is a prime number that is one less than a power of two. In other words, it is a prime number of the form 2k - 1, where k ≥ 2.
Given a positive integer n, return all Mersenne Primes less than or equal to n in increasing order.
Examples:
Input: n = 10
Output: [3, 7]
Explanation: 3 and 7 are the only Mersenne Primes less than or equal to 10.Input: n = 100
Output: [3, 7, 31]
Explanation: 3, 7, and 31 are the only Mersenne Primes less than or equal to 10.
Table of Content
[Naive Approach] One by One Check Mersenne - O(sqrt(n) * log n) Time and O(1) Space
Generate numbers of the form 2k - 1 up to n and check each candidate for primality using trial division.
Working of the Approach:
- Start with k = 2.
- Generate the Mersenne number 2k - 1.
- If it exceeds n, stop generating further numbers.
- Check whether the generated number is prime by testing divisibility up to its square root.
- If it is prime, add it to the result.
- Increment k and repeat the process.
- Return all the Mersenne Primes in increasing order.
#include <bits/stdc++.h>
using namespace std;
bool isPrime(int n) {
if (n < 2)
return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return false;
}
return true;
}
vector<int> allMersennePrimeNo(int n) {
vector<int> ans;
for (int k = 2; ; k++) {
int num = (1 << k) - 1;
if (num > n)
break;
if (isPrime(num))
ans.push_back(num);
}
return ans;
}
int main() {
int n = 100;
vector<int> ans = allMersennePrimeNo(n);
cout << "[";
for (int i = 0; i < ans.size(); i++) {
if (i > 0)
cout << ", ";
cout << ans[i];
}
cout << "]";
return 0;
}
import java.util.List;
import java.util.ArrayList;
class GFG {
static boolean isPrime(int n) {
if (n < 2)
return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return false;
}
return true;
}
static List<Integer> allMersennePrimeNo(int n) {
List<Integer> ans = new ArrayList<>();
for (int k = 2; ; k++) {
int num = (1 << k) - 1;
if (num > n)
break;
if (isPrime(num))
ans.add(num);
}
return ans;
}
public static void main(String[] args) {
int n = 100;
List<Integer> ans = allMersennePrimeNo(n);
System.out.println(ans);
}
}
def is_prime(n):
if n < 2:
return False
i = 2
while i * i <= n:
if n % i == 0:
return False
i += 1
return True
def allMersennePrimeNo(n):
ans = []
k = 2
while True:
num = (1 << k) - 1
if num > n:
break
if is_prime(num):
ans.append(num)
k += 1
return ans
if __name__ == "__main__":
n = 100
ans = allMersennePrimeNo(n)
print(ans)
using System;
using System.Collections.Generic;
class GFG {
static bool isPrime(int n) {
if (n < 2)
return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return false;
}
return true;
}
static List<int> allMersennePrimeNo(int n) {
List<int> ans = new List<int>();
for (int k = 2; ; k++) {
int num = (1 << k) - 1;
if (num > n)
break;
if (isPrime(num))
ans.Add(num);
}
return ans;
}
static void Main() {
int n = 100;
List<int> ans = allMersennePrimeNo(n);
Console.Write("[");
for (int i = 0; i < ans.Count; i++) {
if (i > 0)
Console.Write(", ");
Console.Write(ans[i]);
}
Console.Write("]");
}
}
function isPrime(n) {
if (n < 2)
return false;
for (let i = 2; i * i <= n; i++) {
if (n % i === 0)
return false;
}
return true;
}
function allMersennePrimeNo(n) {
const ans = [];
for (let k = 2; ; k++) {
const num = (2 ** k) - 1;
if (num > n)
break;
if (isPrime(num))
ans.push(num);
}
return ans;
}
// Driver Code
const n = 100;
const ans = allMersennePrimeNo(n);
console.log("[" + ans.join(", ") + "]");
Output
[3, 7, 31]
[Optimal Approach] Sieve of Eratosthenes - O(n log log n) Time and O(n) Space
The idea is to use the Sieve of Eratosthenes to precompute all prime numbers up to n. Then generate numbers of the form 2k - 1 and use the sieve to check whether each candidate is prime.
Working of the Approach:
- Create a prime array of size n + 1 and initially mark all numbers as prime.
- Use the Sieve of Eratosthenes to mark all composite numbers as non-prime.
- Start with k = 2 and generate the Mersenne number 2k - 1.
- If the generated number exceeds n, stop.
- Check prime[2k - 1] to determine whether the candidate is prime. If it is prime, add it to the result.
- Increment k and repeat until the candidate exceeds n.
- Return the result in increasing order.
#include <bits/stdc++.h>
using namespace std;
vector<int> allMersennePrimeNo(int n) {
vector<bool> prime(n + 1, true);
prime[0] = prime[1] = false;
for (int i = 2; i * i <= n; i++) {
if (prime[i]) {
for (int j = i * i; j <= n; j += i)
prime[j] = false;
}
}
vector<int> ans;
for (int k = 2; ; k++) {
int num = (1 << k) - 1;
if (num > n)
break;
if (prime[num])
ans.push_back(num);
}
return ans;
}
int main() {
int n = 100;
vector<int> ans = allMersennePrimeNo(n);
cout << "[";
for (int i = 0; i < ans.size(); i++) {
if (i > 0)
cout << ", ";
cout << ans[i];
}
cout << "]";
return 0;
}
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class GFG {
static List<Integer> allMersennePrimeNo(int n) {
boolean[] prime = new boolean[n + 1];
Arrays.fill(prime, true);
if (n >= 0) prime[0] = false;
if (n >= 1) prime[1] = false;
for (int i = 2; i * i <= n; i++) {
if (prime[i]) {
for (int j = i * i; j <= n; j += i)
prime[j] = false;
}
}
List<Integer> ans = new ArrayList<>();
for (int k = 2; ; k++) {
int num = (1 << k) - 1;
if (num > n)
break;
if (prime[num])
ans.add(num);
}
return ans;
}
public static void main(String[] args) {
int n = 100;
List<Integer> ans = allMersennePrimeNo(n);
System.out.println(ans);
}
}
def allMersennePrimeNo(n):
prime = [True] * (n + 1)
if n >= 0:
prime[0] = False
if n >= 1:
prime[1] = False
i = 2
while i * i <= n:
if prime[i]:
for j in range(i * i, n + 1, i):
prime[j] = False
i += 1
ans = []
k = 2
while True:
num = (1 << k) - 1
if num > n:
break
if prime[num]:
ans.append(num)
k += 1
return ans
if __name__ == "__main__":
n = 100
ans = allMersennePrimeNo(n)
print(ans)
using System;
using System.Collections.Generic;
class GFG {
static List<int> allMersennePrimeNo(int n) {
bool[] prime = new bool[n + 1];
Array.Fill(prime, true);
if (n >= 0) prime[0] = false;
if (n >= 1) prime[1] = false;
for (int i = 2; i * i <= n; i++) {
if (prime[i]) {
for (int j = i * i; j <= n; j += i)
prime[j] = false;
}
}
List<int> ans = new List<int>();
for (int k = 2; ; k++) {
int num = (1 << k) - 1;
if (num > n)
break;
if (prime[num])
ans.Add(num);
}
return ans;
}
static void Main() {
int n = 100;
List<int> ans = allMersennePrimeNo(n);
Console.Write("[");
for (int i = 0; i < ans.Count; i++) {
if (i > 0)
Console.Write(", ");
Console.Write(ans[i]);
}
Console.Write("]");
}
}
function allMersennePrimeNo(n) {
const prime = new Array(n + 1).fill(true);
prime[0] = false;
prime[1] = false;
for (let i = 2; i * i <= n; i++) {
if (prime[i]) {
for (let j = i * i; j <= n; j += i)
prime[j] = false;
}
}
const ans = [];
for (let k = 2; ; k++) {
const num = (2 ** k) - 1;
if (num > n)
break;
if (prime[num])
ans.push(num);
}
return ans;
}
// Driver Code
const n = 100;
const ans = allMersennePrimeNo(n);
console.log("[" + ans.join(", ") + "]");
Output
[3, 7, 31]