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: EASY
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 ** 0.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]


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]