P – smooth numbers in given ranges


P smooth numbers are the numbers that have the maximum prime number that can divide them is less than or equal to the given number P. Prime numbers are the numbers that are divisible by only 1 and that number. 1 is by default considered as the P - smooth number for any given value of P. In this problem, we will be given a value P and the range and we have to return the number of elements that are present in that range and are P-smooth.

Input

Given the value of P is 7 and the range is 10 to 20 (where 10 and 20 are inclusive) and 1 to 10;

Output

10, 12, 14, 15, 16, 18, 20.
1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Explanation

In the given range, the numbers 11, 13, 17, and 19 are the prime number and have the greatest prime divisor equal to themself and are greater as compared to the given value of P.

For the remaining elements, the greater divisor is less than or equal to 7.

For the second range, we have all the elements with the maximum prime divisor less than or equal to p or 7.

Approach 1

In this approach, we will traverse over the given range, and for each element, we will find the greatest prime factor of each number and if that value is less or equal compared to the given number then we will return them.

Example

#include <bits/stdc++.h>
using namespace std;
// function to find the max prime integer 
int maxPrimeDivisor(int cur){
	int res = 1;
   // base condition 
	if (cur == 1) {
		return res;
	}
	while (cur % 2 == 0) {
		res = 2;
		cur = cur / 2;
	}
	// getting the sqrt root 
	int squareRoot = sqrt(cur) + 1;
	for (int i = 3; i < squareRoot; i += 2) {
		while (cur % i == 0) {
			res = i;
			cur /= i;
		}
	}
	// When cur is prime itself
    res = max(res, cur);
	return res;
}
// function to find the P smooth in the given range 
void findPSmooth(int l, int r, int p){
   // traversing over the given range of elements 
   for(int i =l ; i<= r; i++){
      int cur = maxPrimeDivisor(i);
      if(cur > p){
         continue;
      }
      else{
         cout<<i <<" ";
      }
   }
   cout<<endl;
}
int main(){
	int p = 7; // defining the variables 
	int n = 2; // total number of ranges 
	// array to define the ranges 
	int arr[][2] = {{10, 20}, {1, 10}};
	// calling the function to find the result 
	for(int i=0; i<n;i++){
	   cout<<"The elements which are P-Smooth in the range of  "<<arr[i][0]<<" and  "<<arr[i][1]<<" are: "<<endl;
	   findPSmooth(arr[i][0], arr[i][1], p);
	}
	return 0;
}

Output

The elements which are P-Smooth in the range of  10 and  20 are: 
10 12 14 15 16 18 20 
The elements which are P-Smooth in the range of  1 and  10 are: 
1 2 3 4 5 6 7 8 9 10 

Time and Space Complexity

The time complexity of the above code is (N*sqrt(N)*log(N)*M), where N is the maximum element in the range and M is the total number of ranges provided.

The space complexity of the above code is O(1), as we are not using any extra space here.

Approach 2

In the previous approach, we found the p-smooth elements for each range. In this approach, we will get all the elements in the maximum value of the range and then return them.

Example

#include <bits/stdc++.h>
using namespace std;
vector<int> p_smooth;
// function to find the max prime integer 
int maxPrimeDivisor(int cur){
	int res = 1;    
   // base condition 
	if (cur == 1) {
		return res;
	}
	while (cur % 2 == 0) {
		res = 2;
		cur = cur / 2;
	}
	// getting the sqrt root 
	int squareRoot = sqrt(cur) + 1;
	for (int i = 3; i < squareRoot; i += 2) {
		while (cur % i == 0) {
			res = i;
			cur /= i;
		}
	}
	// When cur is prime itself
   res = max(res, cur);
	return res;
}
// function to get the p_smooth elements
void calPSmooth(int mx, int p){
   for(int i=1; i<=mx; i++){
      if(maxPrimeDivisor(i) <= p){
         p_smooth.push_back(i);
      }
   }
}
// function to find the P smooth in the given range 
void findPSmooth(int l, int r){
   // traversing over the given range elements 
   for(int i = 0 ; i< p_smooth.size(); i++){
      if(p_smooth[i] > r){
         break;
      }
      if(p_smooth[i] >= l){
         cout<<p_smooth[i]<<" ";
      }
   }
   cout<<endl;
}
int main(){
	int p = 7; // defining the variables 
	int n = 2; // total number of ranges 
	int mx = 100; // maximum range 
	// array to define the ranges 
	int arr[][2] = {{10, 20}, {1, 10}};
	// calling the function to get all the pSmooth elements 
	calPSmooth(mx,p);
	// calling the function to find the result 
	for(int i=0; i<n;i++){
	   cout<<"Element which are P-Smooth in the range "<<arr[i][0]<<" "<<arr[i][1]<<" are: "<<endl;
	   findPSmooth(arr[i][0], arr[i][1]);
	}
	return 0;
}

Output

The elements which are P-Smooth in the range of 10 and 20 are: 
10 12 14 15 16 18 20 
The elements which are P-Smooth in the range of 1 and 10 are: 
1 2 3 4 5 6 7 8 9 10 

Time and Space Complexity

The time complexity of the above code is (M*sqrt(M)*log(M) + N), where N is the maximum element in the range and M is the total number of ranges provided.

The space complexity of the above code is O(M), as we are storing p smooth elements.

Conclusion

In this tutorial, we have implemented a code to find the P-Smooth numbers in the given range. P smooth numbers are the numbers that have the maximum prime number that can divide them is less than or equal to the given number P. We have implemented codes with time complexity of (M*sqrt(M)*log(M) + N) and (N*sqrt(N)*log(N)*M). Also, the space complexity of O(1) and O(M).

Updated on: 01-Sep-2023

71 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements