This is the code I know:
bool checkPrime(int n) {
bool prime = true;
for (int i = 2; i < n; i++) {
if ((n%i) == 0) {
prime = false;
}
}
return prime;
}
But is this ok if you’re looking for prime numbers:
List<int> arr = [2, 3, 5, 7]; // Already known
int n = 30; // Between 1 to 30. It could be any number
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0) {
arr.add(i);
}
// Then maybe some code for numbers less than 8
}
print(arr);
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
And also is there much difference in time complexity?
Your code is incorrect.
This code only works because you are taking the value of n as 30, for a greater number like 1000 this will produce an incorrect result.
List arr = [2,3,5,7]; // already known
int n = 1000; // between 1 to 1000 it could be any number
List<int> arr = [2,3,5,7];
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0){
arr.add(i);
}
//Then maybe some code for numbers less than 8
}
print(arr);
Your code will return 231 prime numbers when there are actually only 168 prime numbers.
This is because you are not considering the future prime numbers that can only be divided by a prime number between 7 to that number.
eg: 121 will be returned by you as prime but it is a multiple of 11
Extending your pattern.
Though this will be faster since it has reduced a number of division operations but due to two loops, it will still be N square.
Here I am simply only dividing numbers from the existing prime numbers collection and adding them in the collection if prime is found tobe used in next iteration for division.
List < int > arr = [2]; // taking 2 since this is the lowerst value we want to start with
int n = 30; // n can between 2 to any number
if (n < 3) {
print(arr); // can return from here.
}
// since we already have added 2 in the list we start with next number to check that is 3
for (int i = 3; i < n; i++) {
bool isPrime = true;
for (int j = 0; j < arr.length; j++) { // we iterate over the current prime number collection only [2] then [2,3]...
if (i % arr[j] == 0) { // check if number can be divided by exisiting numbers
isPrime = false;
}
}
if (isPrime) { // eg: 2 cant divide 3 so we 3 is also added
arr.add(i)
}
}
print(arr);
You can look a faster pattern here.
Which is the fastest algorithm to find prime numbers?
Related
This was asked during my interview. I have to write a program to find all the prime numbers which are having only odd digits in them for the given range.
Eg: 31 is a prime number having only odd digits in it 3 & 1.
Eg: 23 is a prime number but it is not having odd digits in it, because it has digit 2.
Now I have one more constraint, to my program, I will pass a variable called temp.
Now if this temp is 1 then I should find the primes, with digits containing only <= 5.
If this temp is 2 then I should find the primes, with digits containing only >= 5.
Sample Input:
If the start position is 30 & end position is 40 with temp value as 1. The possible prime numbers are 31, 37 in the 30 to 40.
31 prime has digits 3 & 1 => so these digits are <= 5.
Now if my temp input data is `1` then the program should return me 1.
If suppose my temp input data is `2` then the program should return me 0.
37 is a prime number with digits 3 & 7. Here 3 <=5 and 7 >= 5. So we should not count this prime number as it will not fall under any category defined for my temp variable.
So for input values start=30, end = 40, temp = 1 output should be 1.
(because of prime number 31).
I have come up with the below code:
public static int process(int start, int end, int temp) {
List<Integer> matching = new ArrayList<>();
// loop from start to end
for (int i = start; i <= end; i++) {
// 0 & 1 are not primes so skip them
if (i == 1 || i == 0) {
continue;
}
// Check if the number is a prime
if (isPrime(i)) {
// Get the digits of that prime number Eg: 31 has digits 3 & 1
List<Integer> nums = new ArrayList<>();
buildDigits(i, nums);
// Codition to check if we need to consider this prime or not in our result.
boolean flag = true;
for (Integer num : nums) {
// The prime number is has an even digit, so discard it.
if (num % 2 == 0) {
flag = false;
break;
}
// The prime has a digit > 5 where as the restriction falls under step 1, so discard
if (temp == 1 && num > 5) {
flag = false;
}
// The prime has a digit < 5 where as the restriction falls under step 2, so discard
if (temp == 2 && num < 5) {
flag = false;
}
}
// Get the required primes
if (flag) {
matching.add(i);
}
}
}
// Return their count
return matching.size();
}
// Find out all digits in a given number, and put them in the list called nums
public static void buildDigits(int num, List<Integer> nums) {
if (num / 10 > 0) {
buildDigits(num / 10, nums);
}
nums.add(num % 10);
}
// This just finds out if the given input is prime or not
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
if (n <= 3) {
return true;
}
if (n % 2 == 0 || n % 3 == 0) {
return false;
}
for (int i = 5; i * i <= n; i = i + 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
I above code, I have used this link as basis for isPrime to find prime or not.
When I used this code in my interview it cleared only 3 test cases out of 8. The test cases are hidden, I was not clear for what inputs this logic failed.
I have gone through this code in debug mode also, but I was not able to find where I made mistake.
This is a problem from SPOJ. I am getting TLE. Need help to improve its time complexity. There is one test-case that i know will fail. But I will take care of it after the time complexity is reduced.
Ada the Ladybug was on a trip with her friends. They each bought a souvenir there. As all of them are mathematicians, everybody bought a number. They want to modify the numbers to have some connection between each other. They have decided to modify the numbers sou they would have their GCD greater than 1 ( gcd(a1,a2,a3,...,aN) > 1). Anyway it is not easy to change a number - the only thing they can do is to go to a proffesor in mathematics, which could forge a number A into number A+1 or A-1. As this operation is not cheap, they want to minimize number of such operations. A number might be forged any number of times.
NOTE: gcd(a,0)==a (so gcd of two 0 is also 0)
Input
The first line contains an integer 1 ≤ N ≤ 3*10^5, the number of friend who were on trip (and also the number of numbers).
The second line contains N integers 0 ≤ a_i ≤ 10^6
Output
Print a single line with minimum number of operations to make a connection between all numbers.
Example Input
5
3 9 7 6 31
Example Output
2
Example Input 2
9
3 4 5 7 8 9 11 12 13
Example Output 2
6
Example Input 3
5
7 7 11 17 1
Example Output 3
5
APPROACH
First i find the primes upto (largest/2 + 1) element in the given array of numbers(using function findPrimes()). And then for every element in the array, find how many operations are going to be needed for each of the primes to be its divisor. The smallest summation for each prime, I am printing as solution.
CODE
import java.io.*;
public class Main
{
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int largest = Integer.MIN_VALUE;
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
String[] strArr = br.readLine().split(" ");
for(int i = 0 ; i < n ; i++)
{
arr[i] = Integer.parseInt(strArr[i]);
if(arr[i] > largest)
{
largest = arr[i];
}
}
func(n,arr,largest);
}
public static void func(int n,int[] arr,int largest)
{
int[] primes = findPrimes(largest / 2 + 1);
//int[] primes = findPrimes((int)Math.sqrt(largest));
int lenOfPrimes = primes.length;
int[] mat = new int[lenOfPrimes];
for(int j = 0 ; j < lenOfPrimes ; j++)
{
if(arr[0] < primes[j])
{
mat[j] = primes[j] - arr[0];
}
else if(arr[0] % primes[j] == 0)
{
mat[j] = 0;
}
else
{
int rem = arr[0] % primes[j];
mat[j] = Math.min(rem,primes[j] - rem);
}
}
for(int i = 1 ; i < n ; i++)
{
for(int j = 0 ; j < lenOfPrimes ; j++)
{
if(arr[i] < primes[j])
{
mat[j] = mat[j] + primes[j] - arr[i];
}
else if(arr[i] % primes[j] == 0)
{
mat[j] = mat[j] + 0;
}
else
{
int rem = arr[i] % primes[j];
mat[j] += Math.min(rem,primes[j] - rem);
}
}
}
int smallest = Integer.MAX_VALUE;
for(int i = 0 ; i < lenOfPrimes ;i++)
{
if(mat[i] < smallest)
smallest = mat[i];
}
System.out.println(smallest);
}
public static int[] findPrimes(int upto)
{
boolean[] primes = new boolean[upto + 1];
for(int i = 0 ; i < upto + 1 ; i++)
primes[i] = true;
int count = 0;
primes[0] = primes[1] = false;
int limit = (int)Math.sqrt(upto + 1);
for(int i = 2 ; i < upto + 1; i++)
{
if(primes[i] == true)
{
count++;
if(i <= limit)
{
for(int j = i * i ; j < upto + 1 ; j += 2 * i)
{
primes[j] = false;
}
}
}
}
int[] primeContainer = new int[count];
int index = 0;
for(int i = 2 ; i < upto + 1 ; i++)
{
if(primes[i] == true)
{
primeContainer[index++] = i;
if(index == count)
break;
}
}
return primeContainer;
}
}
The solution that you are trying will give you correct answer. But since there are many prime numbers till 1000000, (~ 78000) hence 78000*300000 will definately give you TLE.
Try to think in terms of sieve. The sieve of eratosthenes works in O(nlogn) time.
Now you would have already figured out that you would change numbers such that it is divisible by some prime number. (As in your algorithm you are considering only prime numbers). So now lets take a prime number say 7. Now you need to find number of transformation of numbers from 0 to 3, because you need to change these numbers to 0. Similarly you need to find number of numbers from 4 to 10 as you will change them to 7 to get them divisible by 7 considering minimum operations. Similarly you would do the same to numbers from 11 to 17, changing them to 14, and so on for rest of the numbers till 1000000. You need to do the same for all prime numbers. This can be achieved using sieve.
The number of operations in this case will be n/2 + n/3 + n/5 + n/7 + n/11 + .... ~ nlogn.
You can read more about sieve from here: https://www.geeksforgeeks.org/sieve-of-eratosthenes/
May be its too late but let me answer this.
I was able to sole this problem using below approach.
My Java Solution take 3.8 S on SPOJ for all 15 test cases combine.
1.Find prime divisors of n in O(log n)
Source https://www.geeksforgeeks.org/prime-factorization-using-sieve-olog-n-multiple-queries/
2. While computing factorization store prime divisors in array let say UniquePrimeWhicheDividsAtleastOneNumber[]
here is a catch always keep 2 in this UniquePrimeWhicheDividsAtleastOneNumber if its not available.
UniquePrimeWhicheDividsAtleastOneNumber[0]=2
3. now you can loop through these primes and find the sum of smallest reminders by these primes.
long minTemp = 0, minAns = Long.MAX_VALUE;
for (int i = 0; i < UniquePrimeWhicheDividsAtleastOneNumber.length; i++) {
for (int j = 0; j < n; j++) {
int rem = InputNumbers[j] % UniquePrimeWhicheDividsAtleastOneNumber[i];
minTemp += Math.min(rem, UniquePrimeWhicheDividsAtleastOneNumber[i] - rem);
if (minTemp > minAns)
break;// no need to compute sum of reminders if it exceeded the current minimum.
}
minAns = Math.min(minAns, minTemp);
minTemp = 0;
}
minAns --> is your answer.
I have two questions about this of code.
Can someone explain me, what the if statement is doing exactly. I know that count has to increment every time the test is true, but I'm not sure what the this n % i == 0 is doing.
My second question is, how can I print the return statement's answer on the console?
int n = 10;
countFactors(n);
}
public static int countFactors(int n){
int count = 0;
for (int i = 1; i <= n; i++){
if (n % i == 0) //this line
count++;
}
return count;
}
}
It count the number of divisor in your range 1-n so for example :
if n = 10 the result will be 4 because there are 4 divisor:
1
2
5
10
and about how you print in console :
for (int i = 1; i <= n; i++) {
if (n % i == 0) {
count++;
System.out.println(i);
}
}
System.out.println("Number or disivor = " + count);
You can learn here : Table of divisors
Well, as the name of the method suggests, the count represents the number of divisors that n has.
The if statement tests the following: Is n divisible by i?. in other words: Is n/i a whole number?
if you were to use:
if(n%i == 1)
instead, then it would count the numbers for which: n/i has a remainder of 1.
in order to print the return statement, you can add this line just before the return:
public static int countFactors(int n){
int count = 0;
for (int i = 1; i <= n; i++){
if (n % i == 0)
count++;
}
System.out.println(count);//adding this
return count;
}
The % operator (known as the remainder or Modulus operator) basically divides a number by another and gives you the remainder and nothing else. For instance, if you do 4 % 2, it would give you 0 because 2 goes into 4 evenly. If you would do 4 % 3 it would give you 1 because that's the remainder of 4 / 3. Also look at this website: http://www.cafeaulait.org/course/week2/15.html
The countFactors method loops 1 to n and includes n. If you do 10 % 1, you would get 0 because one goes into 10 evenly so the count would be incremented.
In my current Project Euler problem 5, I have a "working" solution. It works on smaller numbers (the example one in the question), but not on the actual problem, because I'm brute forcing it, and the program doesn't finish.
Here's the explanation of the problem:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible1 by all of the numbers from 1 to 20?
1: Divisible with no remainder
Here is my current code:
package Euler;
public class Euler5 {
public static void main(String[] args) {
int desiredNumber = 20;
boolean exitLoop = false;
long counter = 1;
while(exitLoop == false) {
long loopCounter = 0;
for(int i=1; i<=desiredNumber; i++) {
if(counter % i == 0) {
loopCounter++;
}
}
if(loopCounter == desiredNumber) {
exitLoop = true;
System.out.println(counter);
}
counter++;
}
}
}
You don't have a computer to answer this question. Look: if a number can be divided by each of the numbers from 1 to 20 it means that it should be a multiplication of primes in corresponding powers:
2**4 (from 16)
3**2 (from 9)
5
7
11
13
17
19
so the solution is
16 * 9 * 5 * 7 * 11 * 13 * 17 * 19 == 232792560
since the answer is quite large I doubt if brute force is a reasonable method here.
In general case (for some n >= 2) find out all the prime numbers that are not exeeding the n:
2, 3, ..., m (m <= n)
then, for each prime number a find out the power pa such that
a**pa <= n
but
a**(pa + 1) > n
the answer will be
2**p2 * 3**p3 * ... * m**pm
Possible Java implementation:
public static BigInteger evenlyDivisible(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
else if (n <= 2)
return BigInteger.valueOf(n);
ArrayList<Integer> primes = new ArrayList<Integer>();
primes.add(2);
for (int i = 3; i <= n; i += 2) {
boolean isPrime = true;
for (int p : primes) {
if (i % p == 0) {
isPrime = false;
break;
}
else if (p * p > i)
break;
}
if (isPrime)
primes.add(i);
}
BigInteger result = BigInteger.ONE;
for(int p : primes) {
// Simplest implemenation, check for round up errors however
int power = (int)(Math.log(n) / Math.log(p));
result = result.multiply(BigInteger.valueOf(p).pow(power));
}
return result;
}
...
System.out.println(evenlyDivisible(20)); // 232792560
The number you are seeking is the Least common multiple (LCM) of the numbers 1,2,3,...,20.
By splitting each numbers to the multiplication of its prime factors (easy for small numbers), finding LCM is fairly easy.
The question is:
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
I write the following program which gives the correct output, but it took very long to execute.
What can I do to fasten my program?
public class ep5 {
public static void main(String[] args) {
int n=100,k=0;
boolean check=true;
while(check)
{
k=0;
n++;
for (int i=2;i<21;i++)
if(n%i!=0)
k=1;
if (k!=1)
check=false;
}
System.out.println(n);
}
}
A start would be not to divide by multiples of two.
for (int i=3;i<21;i++){ //begin at i = 3
i = i + 1; //count by twos
if(n%2 !=0 && n%i!=0) //add a condition
k=1;
}
I imagine you could extend this logic to multiples of 3, 5, 7, 11, 13, 17, and 19, all the prime numbers between 1 and 21. Get rid of the for loop and use an else if statements to speed up the process.
if (n%2 !=0)
k = 1;
else if (n%3 != 0)
k = 1;
else if (n%5 != 0)
k = 1;
else if (n%7 != 0)
k = 1;
else if (n%11 != 0)
k = 1;
else if (n%13 != 0)
k = 1;
else if (n%17 != 0)
k = 1;
else if (n%19 != 0)
k = 1;
else
check = false;
Hope that helps.
one can easily see that the smallest number that divide all numbers from 1 to 20 is the product of all (greatest power (of prime numbers smaller than 20) smaller than 20), you can manage to find those numbers and calculate there greater power that is smaller than 20 and multiply theses numbers
what I mathematically do is decompose all these numbers on prime numbers product, and take the biggest power for each prime number.