HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Sum of the digits is prime or not

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thedigitssumprimenot

Problem

Puzzle Description:


A number is called lucky if the sum of its digits, as well as the sum
of the squares of its digits is a prime number. How many numbers
between A and B are lucky?

How can I improve performance of the following code?

import java.util.Scanner;

public class lucky_num {

    public static void main(String[] args) {

        lucky_num sr = new lucky_num();
        Scanner scanner = new Scanner(System.in);
        int no_cases = scanner.nextInt();
        for (int i = 0; i  9) {
            long k = i % 10;
            i = i / 10;
            sum += k * k;
        }
        sum += i * i;
        return (isPrime(sum));
    }

    private boolean isSUM(long i) {
        int sum = 0;
        while (i > 9) {
            long k = i % 10;
            i = i / 10;
            sum += k;
        }
        sum += i;
        return (isPrime(sum));
    }

    private boolean isPrime(int num) {
        if(num==2)
        return true;
        // check if n is a multiple of 2
        if (num % 2 == 0 || num==1 )
            return false;
        // if not, then just check the odds
        for (int i = 3; i * i <= num; i += 2) {
            if (num % i == 0)
            return false;
        }
        return true;
    }
}


Sample input:

2
1 20
120 130


Sample output:

4
1


Constraints:

1 <= T <= 10000
1 <= A <= B <= 10^18

Solution

The maximum sum of squares-of-digits of an \$n\$-digit number is \$n\cdot9\cdot9 = n\cdot81\$. The number of digits in a number \$B\$ is \$\lceil\log_{10}(B)\rceil\$.

Since you only need to sieve to the square root of the number you're testing for primality, you only need to run your sieve from \$3\$ to \$\sqrt{\lceil \log_{10}(B)\rceil\cdot81}\$. Even for \$B\$ = 1 billion, this means the max you need to sieve to is \$28\$.

So, run the sieve once, and simply cache the results.

Also, if you wanted to be really cool, you could probably get some minor speed-ups by not calculating the sums-of-digits, and looping over them instead.

What I mean by that is this: notice that the sum of digits of \$32x\$ (where \$x\$ is any digit - read that as "three hundred and twenty-\$x\$") is always going to be \$3 + 2 + x\$, and the sum-of-squares will always be \$9 + 4 + x^2\$. Thus, instead of looping from \$320\$ to \$329\$ and calculating the sum-of-digits and sum-of-square-of-digits every time, you could just loop from \$x = 0\$ to \$x = 9\$, and check \$3+2+x\$ and \$9+4+x^2\$ for primality.

Using a bit of recursion, you could loop over all values of all digits.

Context

StackExchange Code Review Q#8319, answer score: 10

Revisions (0)

No revisions yet.