1

I am doing a solution to a coding problem, and I tweaked some existing code to be able to figure out how many semi-primes exist up till and including a certain number.

However, I am stuck at the part where I want to count the number of unique semi-primes between two numbers e.g. 10 and 4, which would be 4,6,9 and 10, i.e. 4. My answer is simply saying 10 has 4 semi-primes, 4 has 1 semi-primes, so the sub-primes between them are 4-1 =3. This is where I am going wrong.

Code is here:

public class SemiPrimeRange {
    public static int[] solution(int N, int[] P, int[] Q) {
        int arrSize = P.length;
        int[] arr = new int[arrSize];

        for (int i = 0; i < arr.length; i++) {
            int n = NoSemiPrimes(Q[i]);
            int m = NoSemiPrimes(P[i]);
            arr[i] = n-m;
        }

        for (int i : arr) {
            System.out.println(i);
        }
        return arr;

    }

    public static int NoSemiPrimes(int large) {
        int n = 0;

        boolean[] primeTop = new boolean[large + 1];
        boolean[] semiprimeTop = new boolean[large + 1];
        for (int i = 2; i <= large; i++) {
            primeTop[i] = true;
        }

        for (int i = 2; i * i <= large; i++) {
            if (primeTop[i]) {
                for (int j = i; i * j <= large; j++) {
                    primeTop[i * j] = false;
                }
            }
        }

        int primes = 0;
        for (int i = 2; i <= large; i++) {
            if (primeTop[i])
                primes++;
        }

        for (int i = 0; i < large; i++) {
            semiprimeTop[i] = false;
        }

        for (int i = 0; i <= large; i++) {
            for (int j = i; j <= large; j++) {
                if (primeTop[j]&&primeTop[i]) {
                    if(i*j<=large){
                        semiprimeTop[j*i] = true;
                    }           
                }
            }
        }

        for (int i = 0; i < semiprimeTop.length; i++) {
            System.out.println(semiprimeTop[i]);
        }

        int semiprimes = 0;
        for (int i = 2; i <= large; i++) {
            if (semiprimeTop[i])
                semiprimes++;
        }

        System.out.println("The number of semiprimes <= " + large + " is " + semiprimes);
        return semiprimes;

    }

    public static void main(String[] args) {
        int[] P = { 1, 4, 16 };
        int[] Q = { 26, 10, 20 };
        int N = 26;
        solution(N, P, Q);
    }
Dhruv Ghulati
  • 2,976
  • 3
  • 35
  • 51

1 Answers1

3

If you want number of semi-primes between y and x (y > x), count(y) - count(x) (count(a) is number of semi-primes between a and 1) is not a correct formula because it will omit x if it is semi-prime. Correct formula is count(y) - count(x - 1).

Also note that your code is ineffective because it will count between 1 and the lesser number twice.

The method signature should be

public static int NoSemiPrimes(int small, int large)

and change the loop

int semiprimes = 0;
for (int i = 2; i <= large; i++) {
    if (semiprimeTop[i])
        semiprimes++;
}

to

int semiprimes = 0;
for (int i = small; i <= large; i++) {
    if (semiprimeTop[i])
        semiprimes++;
}

to count the number of semi-primes in desired range directly instead of using int NoSemiPrimes(int large) twice.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70