You are given two positive integers `a` and `b` (`a < b <= 20000`). Complete the function which returns a list of all those numbers in the interval `[a, b)` whose digits are made up of prime numbers (`2, 3, 5, 7`) but which are not primes themselves.


Be careful about your timing!


Good luck :)

Difficulty: introductory

Starter code:

def not_primes(a, b):
	

Solutions:
from math import sqrt
def is_prime(n):
    if n < 2: return False
    for x in range(2, int(sqrt(n)) + 1):
        if n % x == 0: return False
    return True

def all_dig_prime(n):
    for d in str(n):
        if d not in "2357": return False
    return True

def not_primes(a, b):
    res = []
    for i in range(a,b):
        if all_dig_prime(i) and not is_prime(i): res.append(i)
    return res

def not_primes(a, b):
  return list([x for x in [22, 25, 27, 32, 33, 35, 52, 55, 57, 72, 75, 77, 222, 225, 232, 235, 237, 252, 253, 255, 272, 273, 275, 322, 323, 325, 327, 332, 333, 335, 352, 355, 357, 372, 375, 377, 522, 525, 527, 532, 533, 535, 537, 552, 553, 555, 572, 573, 575, 722, 723, 725, 732, 735, 737, 752, 753, 755, 772, 775, 777, 2222, 2223, 2225, 2227, 2232, 2233, 2235, 2252, 2253, 2255, 2257, 2272, 2275, 2277, 2322, 2323, 2325, 2327, 2332, 2335, 2337, 2352, 2353, 2355, 2372, 2373, 2375, 2522, 2523, 2525, 2527, 2532, 2533, 2535, 2537, 2552, 2553, 2555, 2572, 2573, 2575, 2577, 2722, 2723, 2725, 2727, 2732, 2733, 2735, 2737, 2752, 2755, 2757, 2772, 2773, 2775, 3222, 3223, 3225, 3227, 3232, 3233, 3235, 3237, 3252, 3255, 3272, 3273, 3275, 3277, 3322, 3325, 3327, 3332, 3333, 3335, 3337, 3352, 3353, 3355, 3357, 3372, 3375, 3377, 3522, 3523, 3525, 3532, 3535, 3537, 3552, 3553, 3555, 3572, 3573, 3575, 3577, 3722, 3723, 3725, 3732, 3735, 3737, 3752, 3753, 3755, 3757, 3772, 3773, 3775, 3777, 5222, 5223, 5225, 5232, 5235, 5252, 5253, 5255, 5257, 5272, 5275, 5277, 5322, 5325, 5327, 5332, 5335, 5337, 5352, 5353, 5355, 5357, 5372, 5373, 5375, 5377, 5522, 5523, 5525, 5532, 5533, 5535, 5537, 5552, 5553, 5555, 5572, 5575, 5577, 5722, 5723, 5725, 5727, 5732, 5733, 5735, 5752, 5753, 5755, 5757, 5772, 5773, 5775, 5777, 7222, 7223, 7225, 7227, 7232, 7233, 7235, 7252, 7255, 7257, 7272, 7273, 7275, 7277, 7322, 7323, 7325, 7327, 7332, 7335, 7337, 7352, 7353, 7355, 7357, 7372, 7373, 7375, 7377, 7522, 7525, 7527, 7532, 7533, 7535, 7552, 7553, 7555, 7557, 7572, 7575, 7722, 7725, 7732, 7733, 7735, 7737, 7752, 7755, 7772, 7773, 7775, 7777] if x>=a and x<b])


from bisect import bisect
from itertools import product
is_prime = lambda n: n % 2 and all(n % x for x in range(3, int(n ** .5) + 1, 2))
prime_digits = (int(''.join(p)) for k in range(2, 6) for p in product('2357', repeat=k))
non_primes = [n for n in prime_digits if not is_prime(n)]
not_primes = lambda a, b: non_primes[bisect(non_primes, a-1): bisect(non_primes, b-1)]

ok = {i for i in range(22, 7778)
      if set(str(i)) <= set('2357')
      and not all(i%d for d in range(2, i))}

def not_primes(*a):
    return sorted(set(range(*a)) & ok)

from bisect import bisect_left as bisect

base, n = set("2357"), 20000
sieve = [1,0]*((n>>1)+1)
sieve[2] = 0
for i in range(3, n+1, 2):
    if not sieve[i]:
        for j in range(i**2, n+1, i): sieve[j] = 1

NOT_PRIMES = [x for x in range(n) if sieve[x] and not (set(str(x))-base)]

def not_primes(a, b):
    end = bisect(NOT_PRIMES, b)
    return NOT_PRIMES[bisect(NOT_PRIMES, a, 0, end): end]

ok = {i for i in range(2, 7778) if set(str(i)) <= set('2357') and not all(i%d for d in range(2, i))}

def not_primes(*a):
    return sorted(set(range(*a)) & ok)

from collections import defaultdict
from bisect import bisect_left

def gen_res(n):
    D = defaultdict(list)
    for q in range(2, n):
        if q not in D:
            D[q*q] = [q]
        else:
            if all(c in allowed for c in str(q)):
                yield q
            for p in D[q]: D[p+q].append(p)
            del D[q]
            
allowed = set("2357")
res = list(gen_res(20000))

def not_primes(a, b):
    return res[bisect_left(res, a):bisect_left(res, b)]

import numpy as np

xs = np.zeros(20001)
xs[:2] = xs[2*2::2] = 1
for i in range(3, int(len(xs)**0.5)+1, 2):
    xs[i*i::i] = 1
n_primes = np.array([i for i in range(1, 20001) if xs[i] and all(c in '2357' for c in str(i))], dtype=int)

def not_primes(a, b):
    return n_primes[np.searchsorted(n_primes, a):np.searchsorted(n_primes, b)].tolist()

def prime_digits(num):
    primes = [2, 3, 5, 7]
    while num:
        if num % 10 not in primes:
            return False
        num //= 10
    return True 
primes = set([2] + [n for n in range(3, 20000, 2) if all(n % r for r in range(3, int(n ** 0.5) + 1, 2))])
def not_primes(a, b):
    return [i for i in range(a, b) if prime_digits(i) if i not in primes]