Consider the range `0` to `10`. The primes in this range are: `2, 3, 5, 7`, and thus the prime pairs are: `(2,2), (2,3), (2,5), (2,7), (3,3), (3,5), (3,7),(5,5), (5,7), (7,7)`.
Let's take one pair `(2,7)` as an example and get the product, then sum the digits of the result as follows:  `2 * 7 = 14`, and `1 + 4 = 5`. We see that `5` is a prime number. Similarly, for the pair `(7,7)`, we get: `7 * 7 = 49`, and `4 + 9 = 13`, which is a prime number. 
You will be given a range and your task is to return the number of pairs that revert to prime as shown above. In the range `(0,10)`, there are only `4` prime pairs that end up being primes in a similar way: `(2,7), (3,7), (5,5), (7,7)`. Therefore, `solve(0,10) = 4)`
Note that the upperbound of the range will not exceed `10000`. A range of `(0,10)` means that: `0 <= n < 10`.
Good luck!
If you like this Kata, please try 
[Simple Prime Streaming](https://www.codewars.com/kata/5a908da30025e995880000e3)
[Prime reduction](https://www.codewars.com/kata/59aa6567485a4d03ff0000ca)
[Dominant primes](https://www.codewars.com/kata/59ce11ea9f0cbc8a390000ed)
from itertools import compress, combinations_with_replacement
import numpy as np


s = np.ones(10001)
s[:2] = s[4::2] = 0
for i in range(3, int(len(s)**0.5)+1, 2):
    if s[i]:
        s[i*i::i] = 0
PRIMES = list(compress(list(range(len(s))), s))

def solve(a, b):
    i, j = np.searchsorted(PRIMES, a), np.searchsorted(PRIMES, b)
    return sum(s[sum(map(int, str(x * y)))] for x, y in combinations_with_replacement(PRIMES[i:j], 2))

from itertools import compress, combinations_with_replacement
import numpy as np


s = np.ones(10001)
s[:2] = s[4::2] = 0
for i in range(3, int(len(s)**0.5)+1, 2):
    if s[i]:
        s[i*i::i] = 0
PRIMES = list(compress(list(range(len(s))), s))

def solve(a, b):
    i, j = np.searchsorted(PRIMES, a), np.searchsorted(PRIMES, b)
    return sum(s[sum(map(int, str(x * y)))] for x, y in combinations_with_replacement(PRIMES[i:j], 2))
