Primes with runs
Problem 111
Considering 4-digit primes containing repeated digits it is clear that they cannot all be the same: 1111 is divisible by 11, 2222 is divisible by 22, and so on. But there are nine 4-digit primes containing three ones:
1117, 1151, 1171, 1181, 1511, 1811, 2111, 4111, 8111
We shall say that M(n, d) represents the maximum number of repeated digits for an n-digit prime where d is the repeated digit, N(n, d) represents the number of such primes, and S(n, d) represents the sum of these primes.
So M(4, 1) = 3 is the maximum number of repeated digits for a 4-digit prime where one is the repeated digit, there are N(4, 1) = 9 such primes, and the sum of these primes is S(4, 1) = 22275. It turns out that for d = 0, it is only possible to have M(4, 0) = 2 repeated digits, but there are N(4, 0) = 13 such cases.
In the same way we obtain the following results for 4-digit primes.
| Digit, d | M(4, d) | N(4, d) | S(4, d) |
| 0 | 2 | 13 | 67061 |
| 1 | 3 | 9 | 22275 |
| 2 | 3 | 1 | 2221 |
| 3 | 3 | 12 | 46214 |
| 4 | 3 | 2 | 8888 |
| 5 | 3 | 1 | 5557 |
| 6 | 3 | 1 | 6661 |
| 7 | 3 | 9 | 57863 |
| 8 | 3 | 1 | 8887 |
| 9 | 3 | 7 | 48073 |
For d = 0 to 9, the sum of all S(4, d) is 273700.
Find the sum of all S(10, d).
from tools import is_probable_prime
number = [0] * 10
def check_number():
if number[0] == 0:
return 0
n = 0
for i in range(len(number)):
n = n * 10 + number[i]
if is_probable_prime(n, [2, 3, 5, 7, 11]):
return n
return 0
def recurse(base_digit, start_pos, level, fill=False):
if level <= 0:
return check_number()
result = 0
if fill:
for pos in range(len(number)):
number[pos] = base_digit
for pos in range(start_pos, len(number)):
for val in range(10):
number[pos] = val
result += recurse(base_digit, pos + 1, level - 1)
number[pos] = base_digit
return result
def run():
result = 0
for d in range(10):
for i in range(1, len(number)):
total = recurse(d, 0, i, True)
if total > 0:
result += total
break
return result
if __name__ == '__main__':
run()
# PERMUTATIONS WITHOUT REPETITION
# Luka Rahne @ http://stackoverflow.com/questions/6284396/permutations-with-unique-values/6285203#6285203
# (modified)
def permutations_wor(elements): # permutations without repetitions
def recurse(listunique, p_list, d):
if d < 0:
yield tuple(p_list)
else:
for i in [j for j in listunique if j[1] > 0]:
p_list[d] = i[0]
i[1] -= 1
for g in recurse(listunique, p_list, d - 1):
yield g
i[1] += 1
listunique = [[i, elements.count(i)] for i in set(elements)]
l = len(elements)
return recurse(listunique, [0] * l, l - 1)
# Primality test function based on Fermat/Euler pseudoprime test.
# To be used for large numbers (>1e6)
def isprimeFE(n): # http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.py
"""
isprimeFE(n) - Test whether n is prime using Fermat and Euler pseudoprime tests.
"""
n = abs(n)
if n == 1 or n == 0: return False
if (n in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]): return True
return isprimeE(n, 2) and isprimeE(n, 3) and isprimeE(n, 5) and isprimeE(n, 7)
def isprimeF(n, b):
"""isprimeF(n,b) - Test whether n is prime or a Fermat pseudoprime to base b."""
return (pow(b, n - 1, n) == 1)
def isprimeE(n, b):
"""isprimeE(n,b) - Test whether n is prime or an Euler pseudoprime to base b."""
if (not isprimeF(n, b)): return False
r = n - 1
while (r % 2 == 0):
r //= 2
c = pow(b, r, n)
if (c == 1): return True
while True:
if (c == 1): return False
if (c == n - 1): return True
c = pow(c, 2, n)
from itertools import combinations_with_replacement
from functools import reduce
def toint(lst):
return reduce(lambda x, y: x * 10 + y, lst)
def runX():
ndigits = 10
sum, lower = 0, 10**(ndigits - 1)
badends = {2, 4, 5, 6, 8, 0}
for d in range(10):
Mnd, Snd = 0, ndigits - 1
while not Mnd:
for padding in combinations_with_replacement(range(10), ndigits - Snd):
root = [d] * Snd + list(padding)
for perm in permutations_wor(root):
if not perm[-1] in badends:
candidate = toint(perm)
if candidate < lower: continue
if isprimeFE(candidate):
Mnd += 1
sum += candidate
Snd -= 1
return sum